我們?cè)趇OS開發(fā)中可能會(huì)遇到同時(shí)開發(fā)多個(gè)類似項(xiàng)目的情況废离。這些項(xiàng)目大同小異侄泽,有諸多代碼可以共用,如果每個(gè)項(xiàng)目都分別開發(fā)蜻韭,這在后期的迭代中會(huì)十分繁瑣悼尾。為了解決這個(gè)問題,使用多Target開發(fā)是一種比較好的選擇肖方,本文就這一技術(shù)實(shí)現(xiàn)進(jìn)行簡(jiǎn)要總結(jié)闺魏。
一、理解項(xiàng)目中的Porject與Target
使用Xcode來開發(fā)項(xiàng)目俯画,其中的Project是一個(gè)整體項(xiàng)目相當(dāng)于一個(gè)倉(cāng)庫(kù)析桥,包括了所有的代碼和資源文件。而Target相當(dāng)于一個(gè)具體的產(chǎn)品,包含了對(duì)于代碼烹骨,資源文件的具體使用規(guī)則和配置。一個(gè)Project可以包含多個(gè)Target材泄,也就是說通過不同Target我們可以生成不同的APP沮焕。
二、多Target開發(fā)項(xiàng)目的實(shí)踐步驟
使用多Target來創(chuàng)建項(xiàng)目拉宗,就以我當(dāng)前正在開發(fā)的親戚買房APP為例峦树。需求是這樣的:親戚買房是一個(gè)為買房人提供砍價(jià)服務(wù)的APP,APP的用戶需要區(qū)分為用戶
旦事, 專家
和砍價(jià)師
三個(gè)用戶群體魁巩。所以這里以Customer,Consultant姐浮,Bargain三個(gè)Target來開發(fā)應(yīng)用
-
以QQMF(親戚買房)為名創(chuàng)建一個(gè)新的工程如下:
-
創(chuàng)建三種Target
創(chuàng)建新Target的方式有兩種:
第一種:依次選擇File->New->Target谷遂,然后選擇一個(gè)模板(通常是Single View App)來創(chuàng)建。只是這樣創(chuàng)建的target帶有Appdelegate和main等文件卖鲤,在這里并不會(huì)用到這些文件肾扰,所以我們采用第二種方式創(chuàng)建。
第二種:
在Targets中點(diǎn)擊已有的Target蛋逾,右鍵選擇Duplicate可以復(fù)制生成一個(gè)copy的新Target集晚,并且在文件目錄中生成對(duì)應(yīng)的copy-Info.plist文件。這樣生成的target與被拷貝的target相似度很大区匣,減少了過多的修改偷拔。通常為了減少后期的修改,我們也會(huì)首先在原有的Target中修改一些配置之后再Duplicate亏钩。
執(zhí)行了Duplicate操作之后的效果如下:
-
修改Targe和plist文件的名稱為自己需要的名稱
在Target里可以直接修改Target的名稱莲绰,在文件目錄下也可以直接修改plist文件的名稱。如果我們不想文件結(jié)構(gòu)那么亂铸屉,也可以像其他文件一樣移動(dòng)plist文件的位置并重新引用到工程中钉蒲,如下:
特別注意:我們?cè)谝苿?dòng)文件的時(shí)候可能需要重新引用文件到工程中,此時(shí)add文件的時(shí)候一定要注意選擇Target彻坛,如果是共用文件一定要勾選對(duì)應(yīng)的Target顷啼,類似AppDelegate這樣文件的操作如下:
-
修改Xcode左上角的Target名稱
選中Xcode左上角的創(chuàng)建工程時(shí)的Target(QQMF),選擇Manage schemes
在如下的schemes中修改Target的名稱昌屉,這里也可以刪除多余的最初的QQMF
特別說明:QQMF是我們創(chuàng)建工程自帶的Target,其實(shí)也可以修改它的名字以供自定義使用钙蒙,而這里我們是直接刪掉了它,這樣之后间驮,項(xiàng)目自帶的info.plist也是沒用的了躬厌,也可以刪掉。
-
設(shè)置Target與plist文件對(duì)應(yīng)
切換到Target目錄下,我們可以在這里刪掉用不到的QQMF扛施,選擇其中一個(gè)Target之后并選擇general鸿捧,然后可以看到每個(gè)Target的右側(cè)都有對(duì)應(yīng)的choose info.plist file選項(xiàng),點(diǎn)擊可以選擇與Target對(duì)應(yīng)的plist文件疙渣。這也就相當(dāng)于不同的Target項(xiàng)目對(duì)應(yīng)了不同的plist配置匙奴。
-
為每個(gè)Target設(shè)置Display Name,Bundle Identifier等信息
點(diǎn)擊Target->選擇General妄荔,我們分別設(shè)置不同項(xiàng)目的名稱和BundleID信息泼菌,以及證書等
-
同一份代碼區(qū)分不同Target的操作
使用多Target是為了共用一部分代碼,但是有些共用的文件在不同的Target下是有細(xì)微不同的啦租,那么我們?cè)诰唧w實(shí)現(xiàn)的時(shí)候就需要作出區(qū)分哗伯。這里解決的方法是針對(duì)不同的Target定義宏。
首先選擇一個(gè)Target,如Customer篷角,依次選擇Build Settings ->搜索PreprocessorMacros, 在找到PreprocessorMacros之后焊刹,我們分別在Debug和Release中設(shè)置TargetType=1如下圖進(jìn)行設(shè)置:
其他的Target也是同樣的設(shè)置方式,只是要區(qū)分TargetType的值内地,分別是2伴澄,3(TargetType及其值都是自定義的)。然后就是在代碼中的使用如下圖阱缓,分別選擇Xcode左上角不同的Target運(yùn)行非凌,查看控制臺(tái)驗(yàn)證是否成功。
-
解決使用Cocoapods的問題
因?yàn)榇嬖诙鄠€(gè)Target荆针,我們需要區(qū)別的設(shè)置不同target需要的第三方庫(kù)敞嗡,如下圖。這里可能出現(xiàn)的問題是如果有很多類似AFNetworking這樣的被多個(gè)Target需要的類庫(kù)航背,我們?cè)趧h除和增加的時(shí)候就會(huì)頻繁的操作而且會(huì)代碼冗余喉悴。
解決上述問題的比較優(yōu)雅的做法是如下:
三、遇到的問題
1.問題:invalid token at start of a preprocessor expression
原因:這是我在pch文件中判斷target類型出現(xiàn)的錯(cuò)誤玖媚,這句話的大致意思是:在預(yù)編譯階段箕肃,代碼并未運(yùn)行,無法判斷宏定義的值今魔。最后查找到原因是我在上述步驟設(shè)置宏定義的時(shí)候勺像,手誤設(shè)置了TargetType==1,這本是一句需要執(zhí)行才能得到結(jié)果的代碼错森。所以無法在#if的條件編譯中通過吟宦。
解決:在條件編譯中不使用代碼運(yùn)行時(shí)才生成的量即可。