最近開始學習完整iOS項目的開發流程和思路,在實際的項目開發過程中,我們通常需要對項目代碼和資料進行版本控制和管理,一般比較常用的SVN或者Github進行代碼版本控制和項目管理。我們iOS項目的開發工具Xcode本來就集成了Github的代碼控制,所以用GitHub會更方便一些,想具體瞭解Xcod ...
最近開始學習完整iOS項目的開發流程和思路,在實際的項目開發過程中,我們通常需要對項目代碼和資料進行版本控制和管理,一般比較常用的SVN或者Github進行代碼版本控制和項目管理。我們iOS項目的開發工具Xcode本來就集成了Github的代碼控制,所以用GitHub會更方便一些,想具體瞭解Xcode和GitHub鏈接具體操作步驟的小伙伴可以戳這裡:iOS學習——Xcode9上傳項目到GitHub。
創建完項目之後,我們再對一個項目進行代碼開發之前,我們首先需要對iOS項目的開發環境進行搭建,我們的應用名稱、項目名稱、應用圖標、啟動圖片等都是在這一步進行設置的,所以這一部分是整個項目開發的基礎,在後續的開發過程中也經常會有些設置需要用到這裡的步驟進行修改。但是目前網上查到的資料都非常簡短和零散,所以今天我們希望對Xcode上iOS項目搭建各種細節都進行一個詳盡的瞭解和學習。
一 Project 和 Targets區別
首先,iOS項目的開發環境搭建主要就是基於我們項目的Project 和 Targets進行展開的。那麼,這兩個東西到底是啥玩意呢?我們點擊我們的項目名,就會出現下圖所示的界面。從圖片中可以看到,在項目導航面板的右側面板上有藍色和紅色框所示的PROJECT和TARGETS兩部分。
PROJECT和TARGETS到底是什麼意思呢?官網的解釋戳這裡:Xcode Concept,看到英文就頭疼的戳這裡看譯文:iOS:[譯]Xcode Concepts--概念Target、Project、Build Setting、Workspace、Scheme。簡單解釋如下:
- project:project是所有文件、資源、信息/配置的repository。一個project包含所有build your products所需的內容並且維護他們之間關係。它可以包含多個targets。一個project為所有的target定義預設的build setting(每一個target可以自定義它們的build setting,這些自定義的setting會覆蓋project預設的build setting,這個在後面會講到)。
- target:簡單地說,target定義了project的編譯設置,確定了project中各種資源和代碼的編譯順序。每個target都唯一依賴於一個project,但是一個project中可以有多個targets,上圖所示的target就有2個(KLBaiSi、KLBaiSiTest),每一個的設置不同,但是同一時間里只有一個active Target,在編譯時我們可以選擇用哪一個target進行編譯,具體操作選擇如下圖所示。
- 一個Target和它的product可以和其他Target聯繫,如果一個target build需要另一個target的“輸出”,可以說成第一個target依賴第二個。如果這倆個target在同一個workspace,Xcode會發現他們的依賴關係,從而build the products按照特定的順序。這樣的關係被稱為“ implicit dependency.” 你也可以為倆個targets指定明確的target 依賴關係在build setting裡面。例如,你可能build一個library和一個鏈接這個library的application(同一個workspace)。Xcode可以發現這種關係並且自動build這個library first。然而,你如果要去鏈接library的某個版本而不是one built in the workspace,你可以在build settings里創建一個確定的依賴關係,它將會覆蓋implicit dependency。
二 project和target的屬性設置
關於project和target的屬性設置,如下圖所示就是project和target的屬性設置界面,左邊是project的屬性設置界面,右邊是target的屬性設置界面。相對而言project的比較簡單,只有info和build setting兩項,畢竟只是對項目資源進行簡單的設置,而target的設置則比較複雜,有general、capabilities、resource tags、 info、build setting、build phases和build rules七項,因為target的每一項設置都直接決定了我們最終App的顯示效果。下麵我們就一一來學習和瞭解各個界面的設置有什麼作用。
2.1 project屬性設置
project的屬性設置有兩塊內容,info和build setting,但是project的build setting和target的build setting之間是相關的,target的build setting的一部分設置會繼承project的build setting部分。所以,project的build setting部分內容就放在2.2target屬性設置部分進行統一講解,本小節就主要瞭解project的info屬性設置部分,info屬性的界面如下:
主要分為三部分:Deployment Target、Configurations和Localizations。
- Deployment Target:部署配置,主要是對本project的生成的App的可以運行的最低版本進行配置,預設是當前Xcode上API的最新版本,所以,在我們的項目中有需要對低版本適配的地方需要在這裡設置。同樣的,我們還可以在build setting中對這一屬性進行設置,兩者是同步的。
- Localizations:本地化,這裡的功能主要是添加我們的App所支持的語言,通過上圖最下麵的紅色圈內的【+】【-】按鈕可以添加或刪除不同的語種,並可以選擇根據手機的設置進行不同語種的自適應。關於最下麵的選擇是否開啟國際化,預設是開啟的,至於如何進行國際化和不同語種的適配詳情見:詳述iOS國際化
- Configurations:用來配置iOS項目的xcconfig文件,主要用於在幾套不同的開發環境編譯。xcconfig文件其實就是xcode里的config文件,本質是一個用來保存Build Settings鍵值對的純文本文件。這些鍵值對覆蓋Build Settings中的值,所以當在xcconfig文件中配置了的選項,在Build Settings中設置將失效。我們在項目中一般不會進行xcconfig文件的自定義。具體xcconfig文件是什麼東東,大家可以查看:iOS之Xcconfig雜談 。估計很多新入門的iOS開發對xcconfig文件都不是很熟悉(其實我也不是很瞭解。。。), 但是大家可能都用過Cocoapods, 其實Cocoapods的項目配置管理很多都是依賴xcconfig文件去實現的。所以在使用Cocoapods進行導包的項目中,我們通過打開.xcworkspace文件,我們會發現project-->info-->configutations下的都有對應的配置文件,而原先沒有用Cocoapods配置的則沒有相關的配置文件,具體區別如下圖所示。
2.2 target屬性設置
在前面我提到了,target的屬性設置的內容比較多,總共有general、capabilities、resource tags、 info、build setting、build phases和build rules七項,接下來我們就一個一個來瞭解和學習。
2.2.1 target的general屬性設置
target的general屬性設置界面如下圖所示,主要分為六個部分,下麵我們隊每一部分的設置的意思進行一個解讀。
- Identify(標識符)欄主要定義了一些和應用發佈有關的標識屬性。
- Display Name(App應用顯示名):安裝到iOS手機或iPad上App的名稱。
- Bundle Identifier(包標識符)是該應用的唯一ID,用來讓操作系統和AppStore識別。在創建項目或者對象過程中Xcode就自行創建了包標識符,一般情況下不要修改它。
- Version(外部版本號)使用戶能夠看到的版本號。
- Build(內部版本號)開發者自己看到的版本號,以區分內部測試版本。
- Signing(簽名)主要是進行證書管理,在真機調試或者打包時我們都需要進行簽名進行認證才可以的。這裡有一個簡單的使用教程,大家有需要可以戳這裡: IOS的Automatically Sign功能,直接在設備上打包。
- Deployment Info(部署信息)定義了一些和應用配置相關的標識屬性。
- Deployment Target(部署對象):用來設置支持的最低版本。這個和project的info中的一個意思,並且,這兩個的設置最好是一樣,如果不一樣,最後的App會以target的設置為準。
- Devices(設備):用來設置支持的設備,有iPhone、iPad和Universal三個選項。
- Main Interface(主界面):應用啟動時預載入的主界面視圖。一般有兩種方法:
- 一種是通過Main.storyboard進行啟動,設置這種方法需要我們整個項目的邏輯和跳轉都在Main.storyboard中完成
- 取消stroryboard的方式啟動主界面,而是通過代碼的方式運行main.m的方法進行啟動,並通過在AppDelegate的 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中指定主界面視圖進行啟動。一般項目中都是採用這種方法進行的,因為一般項目中界面比較多,很多都是通過純代碼的風格進行定義的,這樣方便修改和定位問題,項目的邏輯也更清晰,特別是多人合作的項目,這種風格更適合。
- Device Orientation(設備方向):定義應用支持的方向。有Portrait、Upside Down、Landscape Left(橫評、Home鍵在左)、Landscape Right幾種方向。
- Status Bar Style(狀態欄樣式)
- App Icons and Launch Images:應用圖標和啟動頁面。主要設置三項:應用圖標、啟動圖片和啟動頁面。具體應用圖標和啟動頁面的大小尺寸介紹見官網:Human Interface Guidelines。
- App icon Source(應用圖標):對應著文件資源Assets.xcassets目錄中的AppIcon中的圖片,如下圖所示。最右邊的面板可以選擇添加哪一種或哪幾種設備上的圖標,每一個型號的設備上的圖標的尺寸是不同的。在中間有一個個的小格子,我們將所有切好的圖標直接拖過來,他們會自動找到自己應該放在的格子里。這些小格子主要分為四類:
- Notification:通知時的圖標,類似有應用相關的推送消息時,有時候需要顯示本應用的圖標則會顯示這個尺寸的
- Spotlight:搜索小圖標,當在Spotlight中輸入應用名,搜索結果中出現該應用時的圖標就是這個尺寸的,還有設置里的圖標也是這個尺寸的。
- App:這就是正常的App圖標,安裝好之後在桌面顯示的,或者分享推薦時顯示的應用也是這個尺寸的圖標
- App store:應用商店中的顯示的圖標
- Luanch Image Source(啟動圖片):同樣對應著文件資源Assets.xcassets目錄中的LuanchImage中的圖片,設定了各種情況下的啟動圖片,具體界面就不截圖了,和Appicon一樣,我們將所有切好的圖標直接拖過來,他們會自動找到自己應該放在的格子里。啟動圖片實際上定義了應用啟動後的界面大小,所以在不同機型中我們需要做好適配,見下麵的【啟動頁面在屏幕適配中的作用】。一款App必須設定對應設備的啟動圖片,否則點開應用會是一片黑白。
- Luanch Screen File(啟動頁面文件):是一個storyboard文件,作用與Luanch Image一樣,但是啟動文件的優先順序高於啟動圖片,就是說如果兩個都設置了,那麼啟動頁面以啟動文件為準,如果都沒有設置,則無法啟動。
- 啟動頁面的作用:在我們點擊應用圖標啟動應用時,應用啟動需要一定的操作時間,再啟動期間,為了增強應用程式啟動時的用戶體驗,您應該提供一個啟動圖像。啟動圖像與應用程式的首屏幕看起來非常相似。當用戶在主屏幕上點擊您的應用程式圖標時,iPhone OS會立即顯示這個啟動圖像。一旦準備就緒,您的應用程式就會顯示它的首屏幕,來替換掉這個啟動占點陣圖像。一定要強調的是,之所以提供啟動圖像,是為了改善用戶體驗,並不是為了提供:應用程式進入體驗」,比如啟動動畫。
- 啟動頁面在屏幕適配中的作用:每個機型,比如同時支持iPhone和iPad的程式,需要分別為iPhone跟iPad指定啟動圖片。當舊的iPhone 4的程式,運行在iPhone 5上面,沒有iPhone 5的啟動圖片,就採用相容模式,上下留黑邊。當為iPhone 5指定了新的啟動圖片,系統就認為這個應用程式是已經適配了iPhone 5的。當舊的iPhone 5程式運行在iPhone 6上面,假如沒有經過適配。舊程式自動等比放大,鋪滿新手機,舊程式也可以正常運行。這種方案可算是自動適配。但因為舊程式拉伸了,整體看起來有點虛,也不能更好利用大屏空間。當需要開發者手動適配的時候,跟iPhone 4過渡到iPhone 5一樣,在新程式中,指定一張新的啟動圖片。當指定了啟動圖,系統就認為應用已經做好了屏幕適配,屏幕解析度就變成應有的大小。在某機型上,如果是自動適配,比如iPhone 5,老版程式就會在屏幕上、下倆端多出倆塊黑條;比如iPhone6/6plus,老版程式就會自動等比拉伸。那如何關閉自動適配?指定啟動圖或者使用Launch Screen File.xib,即程式使用手動適配,不會做拉伸等,但是程式內部必須已做處理,否則使用自動適配方案。
- App icon Source(應用圖標):對應著文件資源Assets.xcassets目錄中的AppIcon中的圖片,如下圖所示。最右邊的面板可以選擇添加哪一種或哪幾種設備上的圖標,每一個型號的設備上的圖標的尺寸是不同的。在中間有一個個的小格子,我們將所有切好的圖標直接拖過來,他們會自動找到自己應該放在的格子里。這些小格子主要分為四類:
- Embedded Binaries(綁定二進位文件):用來連接二進位文件,一般在使用第三方SDK的時候使用。
- Linked Frameworks and Libraries(鏈接的框架和庫):選擇要鏈接的框架和庫,既可以是SDK自帶的框架,也可以是第三方框架,在Build Phases中也有類似的功能選項。
2.2.1 target的info屬性設置
target的info屬性設置界面如下圖所示,主要分為五個部分,下麵我們隊每一部分的設置的意思進行一個解讀。
在這一部分,最重要的就是第一部分Custom iOS Target Properties自定義iOS目標屬性,其他的四個部分基本上都不怎麼用,大家不用管就好了。在target的info選項卡中的五項信息與我們項目資源目錄下的info.plist文件中的內容是一致,並且修改其中一個另一個會自動修改。此外,我們在2.2.1中講到的general選項卡中的一些設置也會對應到info.plist文件中,所以這些內容都是相通的,我們修改一處,其他的地方會同步次修改。info.plist中其實載入的信息會非常多,上面是創建項目之後自動生成的一些最基本的設置選項,每一項對應的意思如下解釋:
- Localization native development region : 與本地化設置有關,為預設的開發語言
- Executable file:程式安裝包的名稱
- Bundle identifier:軟體唯一的標識,是根據公司的標識與項目名稱自動生成的,在上傳和測試的時候會用到
- InfoDictionary version:版本信息
- Bundle name:App安裝後顯示的名稱
- Bundle OS Type code:用來標識軟體包類型
- Bundle versions string, short:發佈的版本字元串
- Bundle creator OS Type code:創建者的標識
- Bundle version:應用程式版本號
- Application requires iPhone environment:用於指示程式包是否只能運行在iPhone OS 系統上,預設為YES
- Launch screen interface file base name:歡迎界面的文件名稱
- Main storyboard file base name:預設情況下程式的主入口
- Supported interface orientations:設置程式預設支持的方向
除此之外,我們在開發過程可能還需要添加一些其他的信息,包括一些許可權的添加,網路許可權、定位許可權、讀寫聯繫人許可權等等,應用白名單的添加等都是在這裡進行配置的。關於info.plist的具體信息和內容詳情參見:Xcode中的Info.plist欄位列表詳解。
另外四部分的簡單解釋:
- Document Types 文檔類型:定義了應用程式所能識別的文檔類型,並且還可以定義在系統中顯示的該類型文檔的自定義圖標。
- Exported UTIs 導出的UTI:UTI Uniform Type Identifiers同一類型標識符。
- Imported UTIs 導入的UTI:
- URL Types URL類型:用來定義URL以便讓應用程式理解應用間交換的數據結構。可用於:IOS喚醒其他程式,程式間相互調用。例如::在URLTypes中URLSchemes中組冊AAPP;在B程式中,openUrl:[NSURL urlWithString:@"AAPP:"];註意":"冒號,沒有冒號是不能成喚醒另一個程式的。其次如果參數中有“&”特殊字元穿,建議對參數進行base64轉換。
2.2.3 target的capabilities屬性設置
target的capabilities屬性設置這一塊主要是一些性能設置開關選擇,例如推送通知、雲存儲、游戲中心、後臺模式等,我們選擇需要的開關進行打開或者關閉,這些相應的狀態都會在info.plist中進行修改。所以,同樣的,我們也可以在info.plist添加一些許可權或性能開關之後,在target的capabilities中也會進行相應的修改的。具體的界面如下圖所示:
2.2.4 target中的Resource Tag屬性設置
target中的Resource Tag選項卡主要是為項目中的資源進行添加tag分類,方便我們對齊載入順序和載入時機進行選擇和設置,即實現按需載入,在需要的時候才載入資源,屬性設置界面如下圖所示。這樣做的好處就是可以實現如下幾種資源載入形式:
- 初始資源的延遲載入:app有一些資源是主要功能要用到的,但在啟動時並不需要。將這些資源標記為“初始需要”。操作系統在app啟動時會自動下載這些資源。例如,圖片編輯app有許多不常用的濾鏡。
- app資源的延遲載入:app有一些只在特定情景下使用的資源,當應用可能要進入這些場景時,會請求這些資源。例如,在一個有很多關卡的游戲中,用戶只需要當前關卡和下一關卡的資源。
- 不常用資源的遠程存儲:app有一些很少使用的資源,當需要這些資源時會去請求它們。例如,當app第一次打開時會展示一個教程,而這個教程之後就可能不會在用到。app在第一次啟動時請求教程的資源,這之後只在需要展示教程或者添加了新功能才去請求該資源。
- 應用內購買資源的遠程存儲:app提供包含額外資源的應用內購買。app會在啟動完成後請求已購買模塊的資源。例如,用戶在一個鍵盤app內購買了SuperGeeky表情包。應用程式會在啟動完成後請求表情包的資源。
- 第一次啟動時必需資源的載入:app有一些資源只在第一次啟動時需要,之後的啟動不再需要。例如,app有一個只在第一次啟動時展示的教程。
關於Resource Tag和按需載入的詳情內容和步驟參見下麵兩篇文章:
2.2.5 target的build setting屬性設置
target的build setting選項卡的是最主要的一部分編譯選項設置,配置界面如下圖所示,界面只是截了一部分,完整的build settings共有20項配置內容。從配置界面上看,每一項的配置都有四列,我們可以看到,從左至右的順序分別是:Resolved列、帶Target圖標列、帶Project圖標列、iOS Default列,每一列所代表的意義如下。
- Resolved列:最終確定的編譯方式,無法自己設定,其結果是根據其右邊三欄的選擇結果以及優先順序順序來確定最後編譯時採用的編譯方式。在圖的第二行選項卡中選擇combined選項,可以直接地看到只有該欄的最後結果。
- 帶Target圖標列:target的build setting配置的編譯選項,可自定義。其優先順序最高,一旦進行設置,則最後的編譯方式以該欄的結果為準。
- 帶Project圖標列:project的build setting配置的編譯選項,可自定義,這一欄的結果與project中build setting選項卡中的結果是一致的,修改其中一個地方,另一處也會自動修改。其優先順序介於target和default之間,當target沒有設置編譯選項,而該欄進行了設置時,則最後的編譯方式以該欄為準。
- iOS Default列:在創建項目時系統自帶的預設編譯選項,無法修改。優先順序最低,只有當其他兩欄都沒有設置選項時,最後的編譯方式才會以該欄為準。
- 優先順序順序:帶Target圖標列 >> 帶Project圖標列 >> iOS Default列。
target的build setting選項卡中的每一行具體所代表的編譯詳情參見:Xcode 編譯選項詳解。
2.2.6 target的build phase屬性設置
target的build phase選項卡的的主要功能是配置編譯器在不同編譯階段的參數,包括編譯所需的資源文件(包括代碼、配置以及各種資源文件),配置界面如下圖所示,主要包括四方面的內容。
- Target Dependencies Target對象依賴階段:某些Target可能依賴某個Target輸出的值,這裡設置依賴。依賴於其他target的輸出的時候,在編譯時系統會自動先編譯被依賴的target,得到輸出值,再編譯當前target。對象依賴階段可以讓Xcode知道必須在當前選擇的對象編譯之編譯的其它依賴對象(比如應用擴展、插件等等)。這個階段是無法被刪除的。
- Compile Sources 源文件編譯階段: 是指將有哪些源代碼被編譯,可以通過紅框中的【+】【-】按鈕進行添加或刪除資源來控制編譯的代碼文件。並且可以通過修改改階段的Compiler Flags(編譯器標識)來為每個單獨文件設置其編譯器編織,比如優化設置等等。
- Link Binary With Libraries 鏈接二進位庫階段:是指編譯過程中會引用哪些庫文件,我們同樣可以通過【+】【-】按鈕進行添加或刪除編譯所引用的庫文件。
- Copy Bundle Resources 複製資源文件階段:是指生成的product的.app內將包含哪些資源文件,同樣可以通過紅框中的【+】【-】按鈕進行添加或刪除資源來控制編譯的資源文件。該階段定義了對象中的資源文件,包括應用程式、圖標、界面構造器、視頻、模板等等。這些資源都會被覆制到安裝包的Contents/Resources文件夾下。
2.2.7 target的build rules屬性設置
關於target的build rules這一塊平時沒有接觸過,也沒有進行相關的設置,網上查詢了半天的資料也沒有找到(囧),如果大家有相關的資料,麻煩評論里留一下,我可以補充上來。