xcode創建一個工程的多個target,便於測試和發佈多個版本

背景:很多時候,我們需要在一個工程中創立多個target,也就是說我們希望同一份代碼可以創建兩個應用,放到模擬器或者真機上,或者是,我們平時有N多人合作開發,當測試的時候,在A這裏裝了一遍測A寫的那塊,當需要測試B寫的代碼時,我們需要到B那裏去裝一遍,如果只有一個target的話,那麼A的將會被覆蓋
還有些時候,我們需要確定到底是A的問題還是B的代碼出了問題,這時候都需要建立一個工程能夠編譯多個版本出來,下文就介紹怎麼在一個工程中編譯多個版本


好了,閒話不多少,下面正式開始:
我們建立一個默認的應用來演示做法:
建立後的應用如下:



可以看到,上面只有一個target:即TestTarget,爲了方便演示,我們給它加上一個多語言,讓它在模擬器上的名字是中文
我們在工程的InfoPlist.strings中增加一句:CFBundleDisplayName="測試正式版;
這樣在模擬器中安裝後顯示的是

好了,前序工作已經可以了

1.新增一個target,因爲這裏我們是建立一個和原來基本一致的target,所以,我們這裏可以選擇複製來新建一個target

當你選擇複製後,會多出兩個文件,如下

還會在scheme那裏多出一個和這個target相關的scheme




2.
上面的名字太難看,我們改個名字,改了名字後,你會發現


重新選擇我們更改後名字的Info plist文件 TestTarget2-info.plist文件(文件名最好是包含info.plist,這個是一個約定,便於以後尋找這個文件)
我們將那個scheme也更改一下



還有生成的product的名字也要改一下,切換到TestTargetTest2的Build Settings下,搜索product name,將product name改成我們需要的名字(注意,這個名字只是我們生成的app的名字,不一定是最後的顯示的名字,最後顯示的名字還要看用戶是否在InfoPlist.strings文件中設置了CFBundleDisplayName="測試1";)





3.切換到TestTargetTarget2這個scheme,運行,
看看模擬器中,你會發現
    模擬器中有兩個測試1了,

有些同學在這裏並沒有生成兩個 圖標,這個應該是他將兩個target的Bundle Identifier都設成了一樣的,這個如果一樣的話,那生成的target會覆蓋上一次的



4.上面已經生成了兩個target,並且也在模擬器上運行成功了,問題來了,我們怎麼知道哪個是哪個呢,兩個的名字是一樣的,不要擔心,這個問題很好解決的



由於共用了一個InfoPlist.stirngs文件,所以,纔會出現兩個target在模擬器上都顯示爲 測試1,知道了問題所在,那麼下面我們就解決它,很顯然,我們應該針對TestTargetTest2再建立一個InfoPlist.stirngs,
由於我們只是需要名字顯示不同,其它都不需要改變的,所以我們可以直接進行復制,將工程目錄下的所有的語言的 InfoPlist.strings文件複製一份,建立一個新的文件夾(注意,需要將所有語言的InfoPlist.strings都複製一份,因爲多語言嘛,語言的文件夾也要有)
如圖


由於我們這裏,只有一種語言,
,所以我們targetTest2中只有一個en.lproj文件夾,將targetTest2文件夾下的InfoPlist.strings中的 



將剛添加的文件加到工程中來


添加完後,將原來那個Infoplist.stirngs的target中的targetTest2去掉如下圖:



將目錄targetTest2下的Infop.stirngs中的內容修改成 測試2



5.先選TestTarget這個scheme,運行,在模擬器上會出現 測試1,切換scheme爲TestTarget2,運行,在模擬器上將生成 測試2

切換scheme如圖


一切正確後在模擬器上將會顯示





6.作爲附錄,其實也比較重要的是,我們很多target共用的代碼,資源等,有時候我們在代碼中需要區分到底是哪個target,比如說,我們生成的第二個target是一個受限版本,我們需要提示用戶(比如是功能受限的免費版本),怎麼在代碼中區分呢?
有如下三個方式
第一種方式,利用CFBundleIdentifier來判斷
  1. NSString*BundleIdentifier =[[[NSBundlemainBundle]infoDictionary]objectForKey:@"CFBundleIdentifier"];// Do any additional setup after loading the view, typically from a nib.
       
    if ([BundleIdentifierisEqualToString:@"yohunl.TestTarget2"]) {
           
    //處理代碼
           
    NSLog(@"TestTarget2-Info.plist");
        }
       
    else {
           
    //處理代碼
           
    NSLog(@"TestTarget-Info.plist");
        }
    第二種方式,定義一個編譯器宏,來進行區分,在
    打開TestTarget2,


注意,上面的 -D是需要的,一般我們對於這種定義宏都大寫的
在代碼中可以
#ifdef TARGET2
    //target2的處理代碼
    NSLog(
@"TARGET2");
#else
    NSLog(@"TARGET1");
#endif


第三種方式,這種不需要增加-D的
增加預編譯宏


在代碼中
#ifdef TESTTARGET2
    //target2的處理代碼
    NSLog(
@"TESTTARGET2");
#else
  
    
NSLog(@"TARGET1");
#endif

以上三種方式都可以的
發佈了25 篇原創文章 · 獲贊 10 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章