iOS - 創(chuàng)建大量相似App的另外一種選擇

本篇文章主要針對iOS應(yīng)用開發(fā)中, 針對需要創(chuàng)建許多相似的應(yīng)用App提出一種新穎的解決方案。

關(guān)于如何創(chuàng)建大量相似的App,iOS大神@唐巧曾在他的博文《猿題庫iOS客戶端的技術(shù)細(xì)節(jié)(一):使用多target來構(gòu)建大量相似App》提出了一種可行性非常高的解決方案。我本人也將該實現(xiàn)方案應(yīng)用到了某二手車應(yīng)用開發(fā)中, 通過創(chuàng)建多個target的方式創(chuàng)建了N個某某拍的應(yīng)用度帮。但是這種方案真的適用于所有場景么? 除了使用這種方案能否有其它的方式去解決這個問題呢?

基于多Target的應(yīng)用實踐

我剛開始接觸到開發(fā)多個相似App應(yīng)用的需求的時候, 也采用了多個target的解決方案腺办。主要做了以下工作:

  1. 建立多個Target (通過Duplicate行為)
  2. 為每一個Target指定LaunchImage和IconImage, LauchImage和IconImage由同一個image assert管理
  3. 為每一個Target指定了Info.PlistInfoPlist.strings, InfoPlist.strings的作用僅僅是為了指定CFBundleDisplayName
  4. 為每一個Target創(chuàng)建了一個用于配置應(yīng)用特征的JSON描述文件, 用于對每個Target的特征進(jìn)行配置修改。
  5. 部署自動化打包平臺孽拷,防止有N個Target就手動打N次包。
配置Configuration的各個xcconfig

在上述工作中, 1半抱、2脓恕、3均和配置項有關(guān), 5與項目開發(fā)無關(guān), 4是和具體的開發(fā)業(yè)務(wù)相關(guān)的膜宋。每一項的配置都沒有什么技術(shù)深度和難度, 4的實現(xiàn)和具體需求相關(guān), 對于極度相似的應(yīng)用更多的行為是換膚和換key。

這里稍微提以下關(guān)于InfoPlist.strings的指定, 每一個Target只能識別一個InfoPlist.strings, 而且還不能重命名炼幔。需要為每一個Target創(chuàng)建一個物理文件夾, 然后在對應(yīng)的文件夾下放置InfoPlist.strings防止命名沖突, 每一個InfoPlist.strings只能指定唯一識別的Target對象激蹲。(原理我還沒有找到, 找到我就更新下博文哈~)

差異性較大的Target處理

什么? 差異性大你還放在一個工程里? 架構(gòu)就有問題。是的, 差異性較大的工程就應(yīng)該拆分成不同的工程, 然后共享的代碼通過framework以及靜態(tài)庫引用的方式抽離出去江掩。<font color='orange'>但是, 時間是道坎!</font> 假如你時間很緊怎么辦? 本文給出一種時間很緊時候的<font color='red'>臨時</font>解決方案(注意: 決必是臨時的, 時間是海綿, 需要去擠的!)

在時間非常緊的情況下, 可以通過拆分AppDelegate來實現(xiàn)(代價其實非常沉重, 會link好多無用的類)学辱。拆分AppDelegate其實就要在main.m里面賦值不同的AppDelegate即可實現(xiàn)。main函數(shù)中argv包含了app的名字, 可以通過該名字去鑒別載入的AppDelegate环形。

#import <UIKit/UIKit.h>

#import "STAppDelegate.h"
#import "STPAppDelegate.h"

int main(int argc, char * argv[])
{
    @autoreleasepool {
        char demoStr[] = "/stdemo.app"; // 檢查stdemo target
        char *p= strstr(*argv, demoStr);
        if(NULL != p){
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([STAppDelegate class]));
        }else{
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([STPAppDelegate class]));
        }
    }
}

PS: 切記, 臨時解決方案, 如需根治, <font style="font-size:1.5em">拆分工程</font>!

基于多Target實現(xiàn)的好處

  1. 直觀

    一目了然, 可以看到所有已創(chuàng)建的Target醒目的列在Build列表中策泣。每一個Target都有對應(yīng)的Tagret配置界面可以看到每一個項目配置圖標(biāo)以及Info.plist對應(yīng)信息。

  2. 靈活性高

    可以根據(jù)項目需要Link需要的類, 根據(jù)Target來指定鏈接不同的類和資源文件, 而不用一口氣全部都Link進(jìn)來抬吟。

基于多Target遇到的坑

如果沒有遇到坑, 那就不會去重新尋找一個更好的解決方案了萨咕。基于多Target的方式去創(chuàng)建大量相似的App的坑主要提現(xiàn)在多人協(xié)作上火本。

個人之前在實現(xiàn)多Target項目的時候遇到的問題不多, 但是隨著時間推移, 維護(hù)開發(fā)遇到了兩個比較明顯的問題:

  1. 類的Target指定遺漏

    在多個Target的環(huán)境下, 我們每新建一個類文件都要給類文件指定對應(yīng)的Target, 如果不小心忘記指定對應(yīng)的Target, 則會會在編譯階段報錯危队。

    配置Configuration的各個xcconfig
  2. 配置文件描述龐大, 難以修改

    多個Target會導(dǎo)致項目的pbxproj臃腫, 因為pbxproj文件維護(hù)了項目的所有文件id和group層級關(guān)系, 多一個target就幾乎多了一倍的描述信息, 可想而知, 這個pbxporj文件是有多龐大。

    光文件龐大頂多引起Xcode項目的配置文件加載慢, 但是遇到?jīng)_突的時候可就頭疼了, 幾萬行的描述文件钙畔。

    配置Configuration的各個xcconfig
  3. 配置文件修改不同步

配置文件修改不同步是基于已創(chuàng)建N個Target的前提下, 因為項目的推進(jìn), 需要對每一個項目文件進(jìn)行固定的修改, 但是存在修改遺漏的情況茫陆。

對于這種場景, 有一種比較好的方案是自己動手寫腳本來替換編譯配置項, 保證每一個Target的配置項目均被替換。Mac開發(fā)工具中自帶的PlistBuddy在處理配置項目替換上絕對是個神器擎析。

重新思考

雖然在項目中遇到了不少坑簿盅,但是解決這些坑并不需要大量的時間(那是因為時間被打散了, 組合起來估計也不少了),所以我個人并沒有去重新思考怎么去解決遺漏Target編譯報錯以及項目配置文件不斷沖突的問題揍魂。

觸發(fā)我重新思考是一次機(jī)緣, 經(jīng)過花瓣網(wǎng)某iOS研發(fā)高手(我不知道他名字哇)提點, 他問我基于Cocoapods能否有更好的辦法去創(chuàng)建大量相似的App桨醋。基于Cocoapods本身就是基于Hook, Hook本身就是動態(tài)修改項目配置項, 換言之, <font color='red'>能否通過動態(tài)修改Target的項目配置項去創(chuàng)建大量相似的App呢</font>?

回到文章前面的基于多Target的應(yīng)用實踐的5個步驟, 逐一用替換項目的配置文件(pbcproj)的方式去重新審視现斋。

  1. 不需要建立多個Target, 只維護(hù)一個Target
  2. 主要是icon和launch image的修改, 有兩種方案:
    • 在image.assert預(yù)先放置多個不同名字的資源, 通過修改pbxproj來指定不同的圖片資源
    • 所有的icon和launch image都是用相同名字, 通過腳本動態(tài)替換image.assert中的資源文件(推薦)
  3. 主要針對info.plist和InfoPlist.strings的修改, InfoPlist.string可以通過sed命令去動態(tài)替換, info.plist也可以采取兩種方案來實現(xiàn):
    • 預(yù)先防止多個Info.plist文件, 通過修改pbxcproj來指定不同的info.plist文件
    • target永遠(yuǎn)指定一個Info.plist, 通過腳本動態(tài)替換修改Info.plist(推薦)
  4. 通過JSON描述特性的文件可以單獨防止在工程里, 通過腳本拷貝替換, 也可以利用cocoapods-keys等工具進(jìn)行外部注入
  5. 前面的4個步驟都是依賴于基本動態(tài)替換, 自動化構(gòu)建平臺通過將指定Target的方式, 修改為在編譯器執(zhí)行對應(yīng)的任務(wù)腳本即可完成喜最。

進(jìn)一步優(yōu)化

重新思考<font color='black'>通過外部修改配置項目和資源文件的方式來實現(xiàn)多個類似應(yīng)用功能</font>, 省去了維護(hù)多個target產(chǎn)生的沖突和配置過大的問題。但是, 外部腳本本身也是一個實現(xiàn)成本, 這里針對替換外部腳本提出一個優(yōu)化策略(不一定最優(yōu))庄蹋。

  1. 維護(hù)每個項目的文件夾

    每一個項目就是指原來的每一個target, 文件夾可以保持和原先的target名字保持同名瞬内。該目錄文件夾不參與項目引用, 即不在pbxcproj文件中被描述。該目錄文件夾純粹是提供給外部腳本使用, 與邏輯工程保持獨立蔓肯。

  2. 在第一步的文件夾中抽離變化項目到同一個JSON文件中

    該json文件中描述了所有需要替換的內(nèi)容, 包含image.assert的替換規(guī)則以及info.plist替換規(guī)則等等遂鹊。

  3. 在第一步的文件夾中抽離資源文件

    在該文件夾中防止所有可變化的資源文件, 包含.png振乏、info.plist等等所有可變化差異的項目蔗包。

配置Configuration的各個xcconfig

在前面三步的基礎(chǔ)下, 主要是為了一個目的, 一行腳本替換所有可變信息。(實際上就是提前將變化項維護(hù)在獨立的文件夾中了)

## 動態(tài)變化 demo1 Target
./st_muti_target st_demo1/muti_target.json

## 動態(tài)變化 demo2 Target
./st_muti_target st_demo2/muti_target.json

想要st_muti_target.sh的源碼? 這個自己寫吧慧邮。调限。每個項目都不一樣的舟陆。

總結(jié)

基于建立多個相似App的需求, 和本人實際在項目應(yīng)用中遇到的坑, 提出了一種基于腳本不斷替換配置項目和資源文件的解決方案。該方案主要解決了多Target所帶來的配置文件過大和容易沖突的問題, 但是同時又引入了腳本的維護(hù)成本耻矮。本文也提供了一種降低腳本使用成本和項目耦合的一種方案, 但是仍需要進(jìn)一步優(yōu)化, 并不是最終的解決方案版本秦躯。

多一種方案多一種選擇么, 對于擅長書寫腳本的童鞋們, 用這種方式做大量類似的App(換膚App)可能會是更好的一種選擇喔~

水平有限, 有錯誤之處或者有什么地方?jīng)]有描述清楚, 請大家及時指出哇~

參考文件:

  1. http://blog.devtang.com/blog/2013/10/17/the-tech-detail-of-ape-client-1/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市裆装,隨后出現(xiàn)的幾起案子踱承,更是在濱河造成了極大的恐慌,老刑警劉巖哨免,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡嘁傀,警方通過查閱死者的電腦和手機(jī)和敬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來采桃,“玉大人懒熙,你說我怎么就攤上這事∑瞻欤” “怎么了工扎?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長衔蹲。 經(jīng)常有香客問我定庵,道長,這世上最難降的妖魔是什么踪危? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任蔬浙,我火速辦了婚禮,結(jié)果婚禮上贞远,老公的妹妹穿的比我還像新娘畴博。我一直安慰自己,他們只是感情好蓝仲,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布俱病。 她就那樣靜靜地躺著,像睡著了一般袱结。 火紅的嫁衣襯著肌膚如雪亮隙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天垢夹,我揣著相機(jī)與錄音溢吻,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛促王,可吹牛的內(nèi)容都是我干的犀盟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼蝇狼,長吁一口氣:“原來是場噩夢啊……” “哼阅畴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起迅耘,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤贱枣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后颤专,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冯事,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年血公,在試婚紗的時候發(fā)現(xiàn)自己被綠了昵仅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡累魔,死狀恐怖摔笤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情垦写,我是刑警寧澤吕世,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站梯投,受9級特大地震影響命辖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜分蓖,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一尔艇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧么鹤,春花似錦终娃、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至柠新,卻和暖如春窍荧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背恨憎。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工蕊退, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓咕痛,卻偏偏與公主長得像痢甘,于是被迫代替她去往敵國和親喇嘱。 傳聞我的和親對象是個殘疾皇子茉贡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)者铜,斷路器腔丧,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,803評論 6 342
  • 前言 在公司發(fā)展過程中,除了開發(fā)維護(hù)自有品牌外作烟,針對有實力有潛質(zhì)的客戶愉粤,公司還會接受OEM「貼牌開發(fā)」的合作方式。...
    ChamchamBen閱讀 2,968評論 9 7
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,071評論 25 707
  • 又到一年畢業(yè)季,大四的師妹打電話給我敘了好久的舊压恒,最后問了我一個問題影暴,她說“師姐,我最近越來越清晰地意識到自己將要...
    _大臉貓閱讀 534評論 0 0