Xcode 編輯器之Workspace,Project,Scheme,Target


一,前言

最近老是突然對Workspace,Project,Scheme,Target四者的關系有些疑惑,所以查閱資料總結一下。

二,Workspace,Project,Scheme,Target四者的定義
1. Xcode Workspace(可類比為“辦公大樓”)
定義Workspace是組織projects和其他協同工作的一份文檔。
作用:
       1. 它將一些項目以及其他的文檔組織在一起,以便於你基於它們進行工作。一個Workspace可以包含任意個xcode項目,你也可以往里面加一些你想要的文件。

       2.它還維護project和target之間的顯性及隱性的依賴關系。

       3. 默認workspace中的所有Xcode projects都在同一個目錄下構建,稱為workspace build directory,由於所有project的所有文件都在同一個目錄下,所以所有文件都對每個project可見。
           比如兩個project使用同一個庫,則不用復制到另一個project目錄中。

workspace中的每個project都有其獨立id,同時project可以屬於多個workspace,可以單獨打開project或者在其他workspace中打開,且都不用重新配置project或者workspace。

可以使用workspace默認的build 目錄,也可以指定一個。如果project指定了構建目錄,這個目錄會被project構建時所在的workspace的build目錄覆蓋。

創建:File->New->WorkSpace
示例:


2. Xcode project(可理解為“在辦公大樓里的公司”)
   定義:Xcode中的project是一個包含了所有文件、資源以及構建一個或者多個product所需信息的一個倉庫。
            project包含編譯product所用的所有元素,並幫我們組織這些元素之間的關系。一個project可以包含一個或者多個target,target指定了如何編譯product。project定義了其內部所有target的默認編譯配置(每個target可以通過重新設置(重寫)編譯配置來定義自己的特殊編譯配置)。

project包含了以下信息:

1、對如下源文件的引用:
    (1)代碼的.h文件和.m文件
    (2)Libraries 和 frameworks
    (3)Resource files(資源文件,如文本,xml,plist等)
    (4)圖片
    (5)Interface Builder files(xib、storyboard等)

2、用來組織資源文件的group(比如哪個文件放在哪個文件夾路徑下)

3、project級別的編譯配置,比如你對debug、release兩種環境的分別設置。

4、targets的配置,這些配置指定了:
    (1)工程編譯的引用
    (2)工程編譯所需要的資源文件的引用
    (3)工程編譯的編譯配置,包括對其他target和配置的依賴關系,還包括沒有target重寫(覆蓋)的project級別的編譯配置

5、用於debug和測試程序的執行環境,這些執行環境指定了:
    (1)xcode在run或debug時的可執行文件
    (2)傳遞給可執行文件的命令行參數(若有)
    (3)程序運行時設置的環境變量(若有)

一個project可以獨立存在,也可以包含在一個workspace下。 你可以用Xcode schemes來指定當前的target、編譯配置、可執行文件配置。

3. Xcode Scheme(可以理解為“公司里的項目團隊”)
   定義:Xcode scheme 定義了可構建的target的集合、構建時可用的設置以及可執行的測試的集合。
           你可以創建任意數目的scheme,但是同一時刻只有一個是活躍的。你可以指定某一個scheme應該是存儲在project中還是workspace中——如果是存儲在project中,它在所有包含這個project的workspace中都是可用的,若是存儲在workspace中,它只能在當前的workspace中可用。當你選擇一個活躍的scheme,你也就同時選擇了一個運行目的(也就是說,這個產品將要構建在那個硬件結構中)。

4. Xcode Target(可以理解為“公司里項目團隊的產品”)
   定義:一個Targetd指定一個產品來構建並且包含了從項目或workspace的全部(或部分)文件中構建產品的指令。一個target定義了一個單一的產品。

            它來組織構建產品的輸入文件(包含構建產品必需的所有文件:源文件,預編譯這些源文件的指令)。Project 可以包含一個或多個target,每個target產生一個產品,可對應一個不同的應用。構建產品的指令有兩種形式:構建設置和構建階段(Build settings 和 Build phases), 你可以在Xcode的項目editor中檢查並編輯它們。target繼承了project的構建設置。但是你可以在target層次覆蓋任何project的設置。在同一時刻,只有一個target是活躍的。Xcode scheme指定了那個target是活躍的。

            一個target以及由它生成的產品可以與其他的target建立關系。如果構建一個target需要另一個target的輸出,我們就說第一個target依賴於第二個target。如果它們兩個都在同一個workspace中,xcode可以發現這種依賴關系,那么它就會按照需要的順序來構建產品。這種關系叫做隱式依賴。你也可以在你的構建設置中設置顯式依賴,並且你可以指定某兩個xcode可能判定為有隱式依賴的target之間沒有依賴關系。
            例如:你可以構建一個庫以及一個鏈接這個庫的在同一個workspace下的應用程序。xcode可以發現這種關系並且自動先構建這個庫。當然,如果你確實需要鏈接到一個與當前workspace下不同版本的庫中,你可以在你的構建設置中創建一個顯示依賴,這將覆蓋原來的隱式依賴。
三,相關使用方法

1.在一個Xcode頁面建立多個工程

1.1建立一個工作空間MyWorkspace

Xcode里面,建立一個工作空間。File->New->Workspace,命名為Myworkspace,存放在文件夾MyWorkspace中(名字都是可以隨便命名的)。

新建一個workspace

這樣我們就建立了一個空的工作空間。然后我們就可以往這個工作空間中加入幾個Xcode工程。

1.2 使用方法一建立一個普通的Xcode工程MyApp1添加到MyWorkspace

File->New->Project 新建一個名為MyApp1的app工程文件。為了便於管理,我們把他放在MyWorkspace文件夾中。創建完成后
在工作空間的Xcode工程中,File->Add File To "MyWorkplace",選中剛才創建的MyApp1工程。這樣MyApp1工程就添加到了MyWorkplace中了。

創建一個普通的App工程
 
將MyApp1添加到MyWorkspace

1.3. 使用方法二建立一個普通的Xcode工程MyApp2添加到MyWorkspace。

我們用另外一種方法添加一個工程到MyWorkplace工作空間中。
File->New->Project 新建一個名為MyApp2的app工程文件。在存放工程的界面中,將下面的Add to : 選擇成MyWorkspace。這樣MyApp2工程就添加到了MyWorkplace中。到此,我們就可以在一個Xcode的界面中同時管理兩個工程了。

 
建立工程的時候將工程添加到MyWorkspace中

1.4. 建立一個SDK工程MySDK添加到MyWorkspace。實現聯編。

但是多工程使用的精髓並不在這里,而在於兩個工程連編。
我們新建一個名為MySDK的.a庫。然后將這個MySDK工程添加到MyWorkplace,來實現MyApp2與MySDK聯調。
File->New->Project->選擇Static Library ,按照方法二添加到MyWorkspace。然后在MySDK里面創建一個sayHello類方法。在方法中打一個斷點。將.a庫拉到MyApp2里面。在ViewController里面調用sayHello方法。執行之后,斷點就會停在MySDK工程中的里面。這樣就可以在兩個工程進行調試了。

建立一個靜態庫工程,添加到MyWorkspace
 
在MySDK中加一個sayHello方法
 
在MyApp2中調用sayHello方法
 
運行MyApp2,斷點會停在MySDK工程

2.在同一個xcode工程里面創建多個項目
2.1首先,先創建第一個Test1工程(項目),並選中Test1工程

點擊下面的+號

接着,跟創建新項目一樣的操作,創建項目Test2。

點擊『Finish』,就完成在同一工程創建兩個項目了,再創建多個項目,按照以上操作即可。

但有一點需要注意的是:

在同一時間,XCode只能對同一工程中的某一個項目進行操作,具體要操作哪個項目,可以按以下操作:

3.在一個工程創建兩個不同版本的應用

一般來說有兩種實現方法:

  1. 一個把當前工程拷貝然后再修改, 這樣做會導致后期維護成本過高, 每次修改都要同時改兩個工程, 到后期修改簡直提心掉膽, 不過操作傻瓜式.

  2. 另外一個種就是在一個Project里面創建兩個Target, 然后通過判斷Target來修改代碼, 這樣都是基於同一套代碼做修改, 只是部分不相同的地方通過Target來添加不同代碼, 后期修改維護成本低, 推薦大家使用這種方式.

第一步:創建兩個Target:

1.首先先選中Target一個已經存在的版本, 右鍵 Duplicate

blob.png

2. 然后在彈出來的選擇框選擇 Duplicate Only

blob.png

3 創建完之后你的新Target應該是和我的一樣, 接下來我們就要修改Target, Scheme, Info-plist, 如圖這樣修改:

blob.png

blob.png

4.修改完了之后Target, Scheme, plist的名字之后, 你需要在新的Target添加對應的plist文件, 修改CFBundleDisplayName就可以修改應用的名字了.

blob.png

blob.png

blob.png

5.還要記得修改一下Product Name 不然你的Bundle Identifier的后綴名有copy和你的Target名字不一樣, 你還需要在Bundle Setting做一下修改.

blob.png

第二步,開始為兩個不同的應用添加不同的AppIcon, LaunchImage

1. 在這個選擇使用Images.xcassets里面設置AppIcon和LaunchImage, 注意這里一個是AppIcon,另一個是AppIcon-2, 以后編譯Target的時候他就會跟隨這里的設置去拿了開機圖和Icon

blob.png

blob.png

blob.png

2.進入Images.xcassets看下圖片是不是都是勾選了兩個Target, 保持和我下圖一樣的勾選, 如果沒有勾選的話, 你在編譯的不同Target的時候會獲取不到資源.

blob.png

3.選擇不同Target進行編譯, 你的運行結果應該和我的截圖一樣, 有着不同的AppName和AppIcon,還有不同的LaunchImage,但是代碼是共用, 到這里你已經成功了一半了, 接下來你肯定是想知道如何在代碼里面區別不同Target, 然后給它們添加其他的特性.

blob.png

第三步,在代碼里面利用宏定義來區分不同的Traget

1.在Bundle Setting里面設置一下Proprecessor Macros添加一份KFREE  KPRO的參數來區分到底是那個Traget. 在代碼里面為需要用到這個宏去判斷代碼塊.

blob.png

blob.png

2.在代碼里面添加Proprecessor Macros里面宏定義, 你就會發現編譯之前Xcode就會智能的選擇不同代碼. 這樣你就共用一個項目管理兩個不同版本的應用了, 大部分的代碼都復用, 維護管理非常輕松.

blob.png

blob.png

 

 





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM