簡介
.a包是一種非開源代碼共享程序代碼的一種方式醋奠,對于接入方而言丸相,看不到具體實(shí)現(xiàn)蝗柔。通常隨.a包提供給接入方的還有圖片資源包.bundle和提供api接口的.h文件。
制作步驟
注:制作靜態(tài)庫通常伴隨著調(diào)試demo一起晃虫,所以可以先建一個測試demo的工程,再在demo的target下以add a target方式添加靜態(tài)庫和圖片資源包扣墩,但這種方式測試demo跟靜態(tài)庫文件都在一個工程目錄下哲银,個人覺得這不利于開發(fā)中協(xié)同開發(fā)和代碼剝離,所以我喜歡用workspace的方式將demo工程和靜態(tài)庫工程進(jìn)行關(guān)聯(lián)呻惕,但這個可以根據(jù)個人愛好來選擇自己喜歡的方式荆责,并沒有什么不妥,下面主要介紹一下自己使用的方式亚脆。
1.新建一個靜態(tài)庫工程做院,并命名為TestLib。
2.新建一個測試demo濒持,并命名為TestDemo键耕。
3.把TestDemo文件夾拖到TestLib文件夾下,然后打開兩個工程柑营,將TestDemo工程拖到TestLib工程里郁竟,xcode會彈出提示框讓你新建一個關(guān)聯(lián)項目工程的workspace,我們命名為TestLib由境,路徑選擇放在TestLib文件夾下棚亩。
關(guān)掉兩個工程蓖议,打開TestLib文件夾下的TestLib.xcworkspace〖ン。可以看到勒虾,這樣測試demo工程和靜態(tài)庫工程就同在一個workspace中了。
4.如果需要圖片資源包瘸彤,我們可以一個bundle修然。可以看到iOS下并沒有bundle质况,不過OS X下的Framework & Library下有愕宋,其實(shí)是一樣的,我們到時候改一下Base SDK就行了结榄,我們下面新建一個bundle中贝,命名為TLResource(通常bundle的名字與.a庫的名字相同,此處僅為演示使用)臼朗。
這樣target下就多了一個TLResource邻寿,下面我們改一下Base SDK,改成Latest iOS
需要注意的是视哑,Bundle放入的@2x和@3x圖片資源(.png)在默認(rèn)配置下會被轉(zhuǎn)為.tiff格式绣否,使用的時候找不到。解決辦法:找到bundle的工程挡毅,修改:
Buld Settings > COMBINE_HIDPI_IMAGES 設(shè)置為NO
之后在運(yùn)行蒜撮,可以看到圖片正常了。
5.編譯一下TestLib和TLRerource得到.a包.boudle圖片庫和.h頭文件跪呈,就是我們要提供給接入方的全部文件段磨。
6.把上面編譯后得到的文件,引入到TestDemo中庆械,注意不要勾選Copy items if needed選項薇溃,這樣如果編譯TestLib工程后TestDemo中的.a包就是最新的了,但是如果靜態(tài)庫暴露的頭文件有變化的話缭乘,需要刪除引入路徑重新導(dǎo)入靜態(tài)庫文件沐序。
在TestLib中開發(fā)靜態(tài)庫功能,在TLResource中增加圖片文件堕绩,然后在TestDemo中就可以測試我們開發(fā)出來的.a 的功能策幼。
靜態(tài)庫版本
跟普通app開發(fā)類似,靜態(tài)庫分為Debug跟release版奴紧,同時又分為真機(jī)版和模擬器版特姐,即存在四種版本:
- Debug-iphoneos
- Debug-iphonesimulator
- Release-iphoneos
- Release-iphonesimulator
修改debug或release,只需在Edit scheme...中修改Build Configuration即可黍氮。
真機(jī)與模擬器版本唐含,分別選擇真機(jī)或模擬器運(yùn)行浅浮,就會生成對應(yīng)的靜態(tài)庫
暴露的頭文件
如需添加多個暴露的頭文件的話,可以用如下操作
指令集
通常做靜態(tài)庫提供給接入方使用的時候捷枯,需要支持多種設(shè)備滚秩,如果想自己的app在各個機(jī)器都能夠最高效率的運(yùn)行,則需要將Build Active Architecture Only改為NO,Valid architectures選擇對應(yīng)的指令集:armv7 armv7s arm64淮捆。這個會為各個指令集編譯對應(yīng)的代碼郁油,因此最后的 ipa體積基本翻了3倍,Release版本必須NO。
打包
上面說到攀痊,靜態(tài)庫分為真機(jī)桐腌、模擬器、debug苟径、release版本案站,提供給接入方使用的時候,沒特殊說明的話一般都是要提供一個支持在真機(jī)與模擬器上運(yùn)行的release版本涩笤。這樣就需要將真機(jī)與模擬器版本合并嚼吞。首先我們可以在finder下看到這樣的四個文件夾
使用如下命令盒件,將release的真機(jī)與模擬器兩個版本合并
lipo -create Release-iphoneos/libTestLib.a Release-iphonesimulator/libTestLib.a -output Desktop/libTestLib.a
create后面跟的兩個分別是phones靜態(tài)庫版本和iphonesimulator版本的路徑蹬碧,output后面參數(shù)是合并后的版本存放路徑。
合并之后炒刁,打開終端恩沽,找到合并版本,使用下面的命令
lipo -info Desktop/libTestLib.a
可以查看打包好的靜態(tài)庫所支持的cpu架構(gòu)
Architectures in the fat file: Desktop/libJDRedPackets.a are: armv7 i386 x86_64 arm64
Architectures對應(yīng)的設(shè)備
i386 :5及以下模擬器
x86_64:5s及以上模擬器
armv7:3gs~4s
armv7s:5~5c (靜態(tài)庫只要支持了armv7翔始,就可以跑在armv7s的架構(gòu)上)
arm64:5s及以上
開發(fā)時注意事項
由于靜態(tài)庫是集成在接入方工程中使用罗心,所以要注意避免與接入方工程代碼及接入方工程中引入的其他靜態(tài)庫發(fā)生沖突,所以在開發(fā)靜態(tài)庫時需要特別注意幾點(diǎn):
1.類名城瞎、宏定義渤闷、枚舉、通知脖镀、類別等命名時加靜態(tài)庫統(tǒng)一特殊前綴飒箭,以避免命名沖突。
2.類別中方法名也需要加特殊前綴蜒灰,以避免方法覆蓋導(dǎo)致不必要麻煩弦蹂。
3.對于項目中的c、c++中的方法强窖,需要加前綴
4.對于開發(fā)靜態(tài)庫時引入的開源庫凸椿,若體量過大,可外部引用翅溺,提供給接入方時加以說明脑漫,體量小的可以對類名及類中所用枚舉髓抑、通知等加前綴使用。
5.特別需要注意的是在同一個類中多個interface的情況优幸,加前綴時一定要檢查所有的interface启昧,避免遺漏
6.由于一些接入方引入靜態(tài)庫時,對app的體積有嚴(yán)格的控制劈伴,所以在開發(fā)靜態(tài)庫時密末,要盡量精簡代碼,引入開源庫時跛璧,可剔除一些不必要的部分严里,如能用系統(tǒng)提供的方法實(shí)現(xiàn)的功能,盡量不去引入大型第三方庫追城,不然打包出來的.a庫可能體積增加很多刹碾。
引入時xcode配置
接入方引入.a包的時候,如果.a包中同時包含類和類別時座柱,需要修改鏈接器參數(shù)為-ObjC
迷帜,這樣鏈接器就會把靜態(tài)庫中所有的Objective-C類和類別都加載到最后的可執(zhí)行文件中,否則會報unrecognized selector
錯誤色洞。
當(dāng)靜態(tài)庫中只有類別而沒有類的時候戏锹,-ObjC
參數(shù)就會失效了。這時候火诸,就需要使用-all_load
或者-force_load
了锦针。-all_load
會讓鏈接器把所有找到的目標(biāo)文件都加載到可執(zhí)行文件中,但是千萬不要隨便使用這個參數(shù)置蜀!假如你使用了不止一個靜態(tài)庫文件奈搜,然后又使用了這個參數(shù),那么你很有可能會遇到ld: duplicate symbol
錯誤盯荤,因為不同的庫文件里面可能會有相同的目標(biāo)文件馋吗,所以建議在遇到-ObjC
失效的情況下使用-force_load
參數(shù)。
-force_load
所做的事情跟-all_load
其實(shí)是一樣的秋秤,但是-force_load
需要指定要進(jìn)行全部加載的庫文件的路徑宏粤,這樣的話,你就只是完全加載了一個庫文件航缀,不影響其余庫文件的按需加載商架。
crash日志收集
靜態(tài)庫的crash日志收集,應(yīng)該是比較頭痛的事兒芥玉,靜態(tài)庫是要集成到別人的項目中蛇摸,當(dāng)要收集crash日志時,如果引入第三方庫灿巧,如果接入方也使用了相同的第三方日志收集庫赶袄,難免會引起靜態(tài)庫間的沖突揽涮,所以這種方式似乎并不可靠《龇危可以通過系統(tǒng)NSException中提供的NSSetUncaughtExceptionHandler
和NSGetUncaughtExceptionHandler
方法蒋困,收集一些簡單的crash日志信息,然后將收集到的crash日志同步到服務(wù)端敬辣,以供查找問題所在雪标,但這種方式還是很局限,目前對于crash日志收集還需學(xué)習(xí)更多知識溉跃,此部分待續(xù)村刨。