workspace管理靜態(tài)庫和多個(gè)項(xiàng)目, 及cocoaPods的使用

項(xiàng)目背景

項(xiàng)目需求:
在已有項(xiàng)目A的前提下,抽離出一個(gè)和項(xiàng)目A有公共業(yè)務(wù)甚至模塊的項(xiàng)目B勘伺,對(duì)于公共業(yè)務(wù)和模塊當(dāng)然是想維護(hù)一份代碼實(shí)現(xiàn)兩個(gè)項(xiàng)目同步跪腹;差異性在于兩個(gè)項(xiàng)目的主題風(fēng)格、項(xiàng)目模塊架構(gòu)不一致飞醉,有各自獨(dú)立的業(yè)務(wù)和功能冲茸。
開發(fā)思路:
1、copy出另一個(gè)target實(shí)現(xiàn)項(xiàng)目B的業(yè)務(wù)模塊缅帘;否定原因:兩個(gè)項(xiàng)目的UI轴术、架構(gòu)不一致,在didFinishlaunch時(shí)就有差異钦无,這種需要通過判斷當(dāng)前target的方式進(jìn)行差異性開發(fā)逗栽,代碼會(huì)比較雜亂和難以維護(hù),圖片等資源文件的分離使用也很難做到失暂,另外還會(huì)增大開發(fā)包的體積
2祭陷、組件化開發(fā);將公共基礎(chǔ)模塊和業(yè)務(wù)模塊完全獨(dú)立趣席,使用pod管理不同組件,兩個(gè)獨(dú)立項(xiàng)目中進(jìn)行各自的引用醇蝴;否定原因:1)開發(fā)時(shí)間緊迫宣肚,人手不足,完全抽離組件不太理想 悠栓,2)對(duì)于公共業(yè)務(wù)模塊霉涨,兩個(gè)項(xiàng)目的風(fēng)格也不盡相同,某種程度上不能完全獨(dú)立惭适,3)現(xiàn)狀是公共的業(yè)務(wù)模塊也需要開發(fā)升級(jí)笙瑟,抽離出去就需要不停維護(hù),這種不穩(wěn)定狀態(tài)實(shí)際上不適合封裝成組件
3癞志、workspace工作區(qū)開發(fā)往枷;采納原因:1)不同于組件抽離,workspace內(nèi)的靜態(tài)庫可以靈活抽取,不用像組件那樣需要完全和外部解耦错洁,可以把工具秉宿,三方庫,category等自定義的和項(xiàng)目AB公共的業(yè)務(wù)模塊都放在靜態(tài)庫屯碴, 2)由于靜態(tài)庫被項(xiàng)目引用后描睦,圖片資源通過bundle管理并且內(nèi)置于項(xiàng)目,所以圖片資源可以獨(dú)立兩份于兩個(gè)項(xiàng)目中导而,3)公共業(yè)務(wù)只需在靜態(tài)庫中進(jìn)行開發(fā)忱叭,兩個(gè)項(xiàng)目引用靜態(tài)庫就好,靜態(tài)庫把外部使用的類的頭文件設(shè)置好就可以了今艺;
4韵丑、具體開發(fā)過程和遇到的問題,就往下看吧

項(xiàng)目配置

實(shí)際開發(fā)項(xiàng)目:一個(gè)workspace中一個(gè)靜態(tài)庫和兩個(gè)項(xiàng)目

一洼滚、創(chuàng)建workspace工作區(qū)埂息,cocoaTouch static library,projectA 和 projectB

1.1 workspace文件遥巴,不多說千康,直接上圖,創(chuàng)建好后只會(huì)生成一個(gè).xcworkspace文件铲掐,無其他文件生成
選擇創(chuàng)建workspace

1.2 創(chuàng)建靜態(tài)庫拾弃,由于蘋果不支持開發(fā)者使用動(dòng)態(tài)庫,所以我們使用靜態(tài)庫(當(dāng)然也可以選擇動(dòng)態(tài)庫CocoaTouch Framework再改成靜態(tài)庫摆霉,還是有不同的)
選擇創(chuàng)建靜態(tài)庫

靜態(tài)庫最后一步
靜態(tài)庫創(chuàng)建的時(shí)候最好和workspace文件在同一目錄下豪椿,便于管理
1.3 兩個(gè)項(xiàng)目的創(chuàng)建和日常創(chuàng)建項(xiàng)目無異,只是要和靜態(tài)庫一樣携栋,選擇addTo和group到剛剛創(chuàng)建的workspace

最終的文件目錄, 如圖搭盾,兩個(gè)項(xiàng)目一個(gè)靜態(tài)庫在一個(gè)workspace下
workspace文件目錄
二、靜態(tài)庫的配置和項(xiàng)目中的使用

1婉支、由于我們是在workspace中創(chuàng)建靜態(tài)庫鸯隅,和獨(dú)立的靜態(tài)庫使用不同(將.a文件拖拽入項(xiàng)目即可),而是在同一個(gè)workspace里向挖,一起編譯蝌以,具體往下看

1.1 前往靜態(tài)庫的target的Build phases,添加copy Files何之,以便項(xiàng)目中引用靜態(tài)庫暴露的頭文件

如何將靜態(tài)庫中的類暴露出去

1.2 項(xiàng)目引用.a靜態(tài)庫跟畅,Link binary with libraries下,add
libCommonLibrary.a
1.3 訪問靜態(tài)庫的類溶推,#import<CommonLibrary/CommonLibrary.h>
至此徊件,項(xiàng)目中如何應(yīng)用靜態(tài)庫和訪問其類就結(jié)束了奸攻,心好累吧

靜態(tài)庫中xib和圖片資源的管理

先解釋一下這個(gè)過程,在項(xiàng)目A中引入.a靜態(tài)庫庇忌,對(duì)于[NSBundle mainBundle]返回的是項(xiàng)目A的bundle舞箍,那么.a中的xib和圖片資源肯定是不在項(xiàng)目A的bundle中的,所以在.a中如何加載xib和圖片呢皆疹,下面要講疏橄,如何管理靜態(tài)庫中的資源文件

  • 關(guān)于Bundle

對(duì)于bundle可以理解為一個(gè)捆綁包,個(gè)人理解bundle為一個(gè)獨(dú)立的空間略就,而我們的可執(zhí)行(executable)工程捎迫,打包完之后,也是一個(gè)捆綁包表牢,我們稱之為主bundle窄绒,這個(gè)主bundle包含了可執(zhí)行代碼,如各個(gè)viewcontroller的可執(zhí)行代碼崔兴,和相關(guān)資源例如圖片資源等彰导。

使用bundle管理靜態(tài)庫中的xib和圖片資源
  • 在靜態(tài)庫中創(chuàng)建bundle
    入口

    macOS下
  • xib文件的bundle,包含xib文件和xib上所加載的圖片資源敲茄;最后我才發(fā)現(xiàn)的位谋,xib用的圖片必須和xib文件在同一個(gè)bundle中,xib才可以自動(dòng)加載圖片堰燎,如圖


    xib的bundle
  • 圖片資源的bundle掏父,和xib的bundle創(chuàng)建過程一致,圖片的bundle其實(shí)完全可以看做是一個(gè)文件夾

  • 至此秆剪,我創(chuàng)建了三個(gè)bundle赊淑,一個(gè)xib bundle,兩個(gè)圖片bundle(用于兩個(gè)不同風(fēng)格的項(xiàng)目仅讽,內(nèi)部圖片名稱一樣)


    還有一個(gè)XZimgBundle.bundle
bundle如何使用
  • 首先陶缺,bundle其實(shí)是靜態(tài)庫中的資源,因?yàn)楫?dāng)前是在項(xiàng)目中引用靜態(tài)庫洁灵,所以bundle需要拖拽進(jìn)項(xiàng)目饱岸,供項(xiàng)目應(yīng)用,如下


    bundle拖拽入項(xiàng)目
  • xib又和圖片資源不同处渣,不同點(diǎn)在于xib會(huì)變化,修改蛛砰,那就需要靜態(tài)庫重新編譯獲取xib的bundle罐栈,而圖片bundle上面說了其實(shí)就是個(gè)文件夾用于管理圖片,所以在image的bundle創(chuàng)建好之后泥畅,就可以從靜態(tài)庫的target中刪除了荠诬,它的管理就在項(xiàng)目中刪加圖片就是了

  • 最后一點(diǎn),現(xiàn)在bundle都在項(xiàng)目中了,靜態(tài)庫中訪問Bundle其實(shí)就是在訪問項(xiàng)目中的bundle柑贞,那怎么訪問呢方椎?我在靜態(tài)庫中定義了一個(gè)BundleTool

//其中一個(gè)項(xiàng)目的名稱是qmp_ios,這樣可以判斷靜態(tài)庫當(dāng)前是哪個(gè)項(xiàng)目加載的
+ (BOOL)isQMP{
    return [[[NSBundle mainBundle]bundlePath]containsString:@"qmp_ios"];
}
//xib資源所在的bundle
+ (NSBundle *)commonBundle{
    NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"CommonBundle.bundle"];
    NSBundle *bundle1 =  [NSBundle bundleWithPath: path];

    return bundle1;
}
//qmp_ios引入的圖片資源QMPimgBundle.bundle
+ (NSBundle *)qmpImgBundle{
    
    NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"QMPimgBundle.bundle"];
    NSBundle *bundle1 =  [NSBundle bundleWithPath: path];
    
    return bundle1;
}
//xinzhi_ios引入的圖片資源XZimgBundle.bundle
+ (NSBundle *)xzImgBundle{
    NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"XZimgBundle.bundle"];
    NSBundle *bundle1 =  [NSBundle bundleWithPath: path];
    
    return bundle1;
}

+ (NSString *)getBundlePath: (NSString *) assetName{
    NSBundle *myBundle = [BundleTool commonBundle];
    if (myBundle && assetName) {
        return [[myBundle resourcePath] stringByAppendingPathComponent: assetName];
    }
    return nil;
}
//用此類替代[UIImage imageNamed] 訪問正確路徑下的圖片,bundle下的圖片可以直接[UIImage imageNamed: bundle+圖片名]
+ (UIImage*)imageNamed:(NSString*)imageName{
    if ([BundleTool isQMP]) {
        if ([imageName containsString:@"activity_user"]) {
            NSLog(@"----");
        }
        return [UIImage imageNamed:[NSString stringWithFormat:@"QMPimgBundle.bundle/%@",imageName]];

    }else{
        return [UIImage imageNamed:[NSString stringWithFormat:@"XZimgBundle.bundle/%@",imageName]];
    }
    
}

至此钧嘶,bundle的創(chuàng)建和使用就此結(jié)束棠众,而在項(xiàng)目內(nèi)部(不牽扯靜態(tài)庫)用到的圖片及xib和平時(shí)普通的用法還是一樣的,因?yàn)轫?xiàng)目內(nèi)的Bundle就是xib和圖片所在的bundle

靜態(tài)庫中的類和項(xiàng)目中的類如何相互調(diào)用

先講有决,這種workspace機(jī)構(gòu)闸拿,.a靜態(tài)庫只能被項(xiàng)目引用,不能引用項(xiàng)目(項(xiàng)目是可以引用項(xiàng)目的)书幕,那就意味著項(xiàng)目可以隨意調(diào)用.a暴露出來的靜態(tài)庫中的類新荤,那.a如何調(diào)用項(xiàng)目的類呢,以上講了背景台汇,我們的.a不是完全獨(dú)立解耦的苛骨,項(xiàng)目A和B的公共業(yè)務(wù)模塊還在.a里,所以.a 是存在需要調(diào)用項(xiàng)目業(yè)務(wù)模塊的情況的苟呐;

  • 靜態(tài)庫想要訪問項(xiàng)目中的類痒芝?
    如何調(diào)用? 我選擇使用protocol掠抬,.a中定義了一套跳轉(zhuǎn)協(xié)議AppPageSkipProtocol吼野,和一個(gè)跳轉(zhuǎn)工具類LibraryPageSkipTool(其中有一個(gè)代理屬性id< AppPageSkipProtocol >delegate),需要跳轉(zhuǎn)到項(xiàng)目中的地方两波,就用delegate調(diào)用跳轉(zhuǎn)協(xié)議中的api去負(fù)責(zé)跳轉(zhuǎn)瞳步,傳入對(duì)應(yīng)參數(shù)即可
  • 跳轉(zhuǎn)協(xié)議根據(jù)實(shí)際情況,看是否需要傳入?yún)?shù)腰奋,定義block回調(diào)单起,根據(jù)實(shí)際情況隨時(shí)修改添加都可以
  • 跳轉(zhuǎn)工具的delegate,在項(xiàng)目的didFinishLaunch里劣坊,用項(xiàng)目的跳轉(zhuǎn)工具類實(shí)例作為delegate傳給.a 的跳轉(zhuǎn)工具類嘀倒,如 [LibraryPageSkipTool shared].delegate = [AppPageSkipTool shared],項(xiàng)目的跳轉(zhuǎn)工具類AppPageSkipTool內(nèi)部局冰,遵循協(xié)議AppPageSkipProtocol测蘑,實(shí)現(xiàn)協(xié)議方法就可以了
如何使用cocoaPods

上面講過,靜態(tài)庫被引入項(xiàng)目之后康二,編譯執(zhí)行環(huán)境都是項(xiàng)目的環(huán)境碳胳,所以靜態(tài)庫需要的環(huán)境(build phases,三方庫沫勿,系統(tǒng)庫)挨约,項(xiàng)目中也需要實(shí)現(xiàn)配置味混,那么......

  • Podfile如何配置, 如圖,靜態(tài)庫中用到的三方庫诫惭,項(xiàng)目中也需要引入翁锡,項(xiàng)目中另外可以添加項(xiàng)目內(nèi)部需要的庫
workspace 'WorkSpaceQMP.xcworkspace'
target 'CommonLibrary' do
  platform :ios,'8.0'
  project 'CommonLibrary/CommonLibrary.xcodeproj'
  pod 'AFNetworking', '~> 3.1.0'
  pod 'MJRefresh', '~> 3.1.0'
  pod 'SDWebImage'
end

target 'qmp_ios' do
  platform :ios,'8.0'
  project 'qmp_ios/qmp_ios.xcodeproj'
 pod 'AFNetworking', '~> 3.1.0'
  pod 'MJRefresh', '~> 3.1.0'
  pod 'SDWebImage'
  pod 'YYText'
  • 在對(duì)應(yīng)的.a和項(xiàng)目的build phases的Link build Library中添加各自的libPod庫

  • 關(guān)閉workspace,此時(shí)文件目錄夕土,啊馆衔,多么愉快的feel


    最終的目錄結(jié)構(gòu)
最后一個(gè)步驟,git管理

我的一個(gè)不知道是否錯(cuò)了的步驟: 創(chuàng)建倉庫并初始化——>clone到本地文件夾——>代碼復(fù)制到此文件夾——>add,commit,push——>發(fā)現(xiàn)兩個(gè)項(xiàng)目是空隘弊,git提示subModule的相關(guān)信息

  • 正確步驟: 創(chuàng)建倉庫并初始化——>終端 cd到代碼根目錄——>git init初始化倉庫哈踱,add,commit——>重點(diǎn)[git remote add origin 你的遠(yuǎn)程庫地址] ——>獲取遠(yuǎn)程庫同步git pull --rebase origin master——>提交git push -u origin master
    如果Git pull報(bào)錯(cuò): refusing to merge unrelated histories的解決辦法,執(zhí)行下面的命令:git pull origin master --allow-unrelated-histories就可以了
    參考:(https://www.cnblogs.com/xiangxinhouse/p/8254120.html)

創(chuàng)建本地庫和fetch遠(yuǎn)程分支這些前面的步驟這里略過梨熙】停可以自行百度。

解決辦法:

1.cmd進(jìn)入項(xiàng)目的根目錄咽扇。

2.執(zhí)行下面的命令:git pull origin master --allow-unrelated-histories邪财。可以提交成功质欲。

參考:https://www.cnblogs.com/eedc/p/6168430.html

遇到的問題
  • 實(shí)際情況下的.a 配置是很麻煩的树埠,需要引入很多第三方庫,其實(shí)整個(gè)過程和實(shí)際項(xiàng)目中使用是一樣的嘶伟,能使用pod管理的盡量使用cocoaPods管理怎憋,三方庫搞定一個(gè)再導(dǎo)入另一個(gè),不然你都不知道哪個(gè)庫出的問題
  • 靜態(tài)庫配置出現(xiàn)arm64的問題九昧,按照網(wǎng)上的做法大概就可以绊袋,千萬記住,項(xiàng)目要配置靜態(tài)庫相同的環(huán)境铸鹰,所需要的系統(tǒng)庫一定全部導(dǎo)入癌别,有時(shí)候這種情況也會(huì)出現(xiàn)arm64的問題,實(shí)際是項(xiàng)目沒有導(dǎo)入需要支持的三方庫
  • 先配置靜態(tài)庫蹋笼,xcode先build靜態(tài)庫展姐,.a成功了,再build項(xiàng)目
  • Archive問題:報(bào)錯(cuò)XcodeDefault.xctoolchain/usr/bin/strip: can't open temporary file:剖毯。圾笨。。逊谋,解決在.a的build setting中將strip linked product置為NO
  • 打包完成發(fā)現(xiàn)最終的.ipa文件特別大擂达,比原先大了二三十兆,網(wǎng)上搜索一些縮減靜態(tài)庫的方法如下:
    1涣狗、在Build setting里面配置:
    2谍婉、set Generate Debug Symbols to NO
    3、Strip Debug Symbols During Copy flag set to Yes
    4镀钓、同時(shí)Valid Architectures可以根據(jù)實(shí)際情況縮減穗熬;
    目前Xcode默認(rèn)支持iOS的指令集有armv7,armv7s丁溅,arm64唤蔗;armv7只出現(xiàn)在iPhone4、iPhone4S的機(jī)器上窟赏;armv7s只出現(xiàn)在iPhone5妓柜、iPhone5C上;后面的機(jī)器一般都是arm64芯片涯穷;iPhone4棍掐、iPhone4S一般項(xiàng)目可以考慮不支持就在Valid Architectures將armv7刪掉。(經(jīng)測試拷况,只要設(shè)置Valid Architectures就可以了作煌,其他的設(shè)置效果不太明顯)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赚瘦,隨后出現(xiàn)的幾起案子粟誓,更是在濱河造成了極大的恐慌,老刑警劉巖起意,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹰服,死亡現(xiàn)場離奇詭異,居然都是意外死亡揽咕,警方通過查閱死者的電腦和手機(jī)悲酷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來心褐,“玉大人舔涎,你說我怎么就攤上這事《旱” “怎么了亡嫌?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長掘而。 經(jīng)常有香客問我挟冠,道長,這世上最難降的妖魔是什么袍睡? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任知染,我火速辦了婚禮,結(jié)果婚禮上斑胜,老公的妹妹穿的比我還像新娘控淡。我一直安慰自己嫌吠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布掺炭。 她就那樣靜靜地躺著辫诅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪涧狮。 梳的紋絲不亂的頭發(fā)上炕矮,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音者冤,去河邊找鬼肤视。 笑死,一個(gè)胖子當(dāng)著我的面吹牛涉枫,可吹牛的內(nèi)容都是我干的邢滑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼愿汰,長吁一口氣:“原來是場噩夢啊……” “哼殊鞭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起尼桶,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤操灿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后泵督,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趾盐,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年小腊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了救鲤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秩冈,死狀恐怖本缠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情入问,我是刑警寧澤丹锹,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站芬失,受9級(jí)特大地震影響楣黍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜棱烂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一租漂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦哩治、人聲如沸秃踩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吞瞪。三九已至,卻和暖如春驾孔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背惯疙。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國打工翠勉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人霉颠。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓对碌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蒿偎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子朽们,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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