講到了SDK開發(fā),這篇來講講iOS中伴隨SDK開發(fā)的Bundle包巩趁。
Bundle是什么塑顺?你可以理解為iOS中一種特殊的目錄,它可以包含各種資源文件挨稿,如:圖片、音頻京痢、視頻奶甘、xib文件、storyboard文件等祭椰。
為什么會有bundle包臭家?
App工程中引入bundle包主要由兩大來源:
- 提供庫文件的開發(fā)者,同時提供了bundle包方淤。
- App開發(fā)者自己為了集中管理資源而打的bundle包
第二種比較好理解钉赁,我們不討論。這里主要討論第一種情況下這么做的本質(zhì)原因携茂。
提供庫的開發(fā)者你踩,如果他們在庫中有使用到某些資源(聲音、視頻讳苦、圖片或圖標(biāo)等)带膜,那么他們提供庫的同時,也是需要提供這些資源文件的鸳谜。這樣他們的庫才能被我們正常使用膝藕。
下面是重點(diǎn):
- 通常而言,只有打包為靜態(tài)庫的咐扭,如果有需要才應(yīng)該打包一個配套的bundle文件芭挽。動態(tài)庫的資源文件應(yīng)該內(nèi)置到.framework文件內(nèi)部的滑废。因?yàn)?framework自身也是一個bundle,可以包含資源文件览绿。
下面詳細(xì)分析下:
首先說明工程設(shè)置:
SDKDemo:制作SDK庫的工程
SDKApp:應(yīng)用SDK庫的App工程
1. 靜態(tài)庫 VS 動態(tài)庫:
編譯App工程時策严,靜態(tài)庫會被編譯進(jìn)App可執(zhí)行文件中,成為可執(zhí)行文件的一部分饿敲。而動態(tài)庫僅會在App可執(zhí)行文件中通過rpath記錄動態(tài)庫的鏈接加載路徑妻导,在App啟動運(yùn)行時,動態(tài)加載器dyld會根據(jù)rpath的值去正確的加載動態(tài)庫怀各,其本身是不會被整合進(jìn)App可執(zhí)行文件中的倔韭。
2. SDKDemo工程(僅是添加了三張圖片):
3. 將SDKDemo.framework導(dǎo)入SDKApp工程中,編譯SDKApp工程瓢对。在生成的SDKApp.app上右鍵顯示包內(nèi)容:
從中我們沒有看到SDKDemo.framework中的圖片資源文件寿酌。要知道iOS App運(yùn)行時所需的資源文件都是從.app文件中獲取的。既然圖片資源不在該目錄下硕蛹,自然代碼中是引用不到的醇疼。所以為了解決這個問題,我們才需要單獨(dú)打包一個bundle文件法焰,將所有的圖片等資源文件放入其中秧荆,然后把這個bundle文件導(dǎo)入App工程中,這樣編譯后的.app文件將會包含這個bundle文件埃仪。這樣只要代碼中引用對了這個bundle乙濒,圖片將會正確被加載顯示...
4. 再來看看將SDKDemo打包為動態(tài)庫:
和靜態(tài)framework文件不同的是,動態(tài)的framework文件是獨(dú)立存在的卵蛉,其在App運(yùn)行時颁股,是作為一個整體鏈接進(jìn)App的可執(zhí)行文件中的。并且Framework文件本身也是一個Bundle傻丝,通過如下接口可獲取特定的bundle:
- (NSBundle *)bundleForClass:(Class)aClass;
aClass: .framework中任何一個聲明類的類對象
返回值:返回參數(shù)aClass對應(yīng)類聲明所在的.framework(是個bundle對象)
所以在代碼中甘有,可直接通過+ (NSBundle *)bundleForClass:(Class)aClass;獲取到目標(biāo)framework,然后通過bundle對象的- (nullable NSString *)pathForResource:(nullable NSString *)name ofType:(nullable NSString *)ext; 等接口方法獲取framework下面的各種資源文件
此乃動態(tài)framework文件不需要單獨(dú)bundle包的原因桑滩。根據(jù)模塊化梧疲、高內(nèi)聚、低耦合等等這些設(shè)計要求运准,我們也應(yīng)該盡量避免讓一個模塊中的東西分成兩個模塊來發(fā)布,此所謂越簡單越好缭受。
5. 總結(jié)
靜態(tài)庫和動態(tài)庫對資源文件處理方式的不同胁澳,本質(zhì)上是因?yàn)橐粋€App運(yùn)行時只能在自己的沙盒空間內(nèi)加載引用可以找到的資源,對于找不到的資源就會出現(xiàn)加載不了的情況米者。通過上面的實(shí)踐可以知道韭畸,靜態(tài)framework中的圖片在打包App時是不會將它的圖片資源文件包含進(jìn)來的宇智。而動態(tài)庫最終會在.app文件內(nèi)創(chuàng)建一個Frameworks目錄,里面是所有App引入的動態(tài)庫胰丁,只要定位到某個動態(tài)framework随橘,自然就可以找到它下面的圖片等資源文件了...