spec.ios.resource_bundle = { 'MapBox' => 'MapView/Map/Resources/*.png' } |
spec.resource_bundles = { |
1.2 resources
使用 resources
來指定資源,被指定的資源只會簡單的被 copy 到目標工程中(主工程)。
We strongly recommend library developers to adopt resource bundles as there can be name collisions using the resources attribute. Moreover, resources specified with this attribute are copied directly to the client target and therefore they are not optimised by Xcode.
官方認為用 resources
是無法避免同名資源文件的沖突的,同時,Xcode 也不會對這些資源做優化。
Examples:
spec.resource = 'Resources/HockeySDK.bundle' |
spec.resources = ['Images/*.png', 'Sounds/*'] |
2. 圖片資源的管理
我們熟知平常用的 @2x @3x 圖片是為了縮小用戶最終下載時包的大小,通常我們會將圖片放在 .xcassets
文件中管理,新建的項目也默認創建:
使用 .xcassets
不僅可以方便在 Xcode 查看和拖入圖片,同時 .xcassets
最終會打包生成為
Assets.car
文件。對於 Assets.car
文件,App Slicing 會為切割留下符合目標設備分辨率的圖片,可以縮小用戶最終下載的包的大小。
FYI:
Xcode Ref Asset Catalog Format
App thinning overview (iOS, tvOS, watchOS)
實際上,對於 Pods 庫的資源,同樣可以使用 .xcassets
管理。
3. 實際驗證
不關注的可以直接跳到下面『結論』
官文中推薦了 resource_bundles
其理由主要是『可以解決同名沖突』和『Xcode為 bundle 提供的一些優化』。
我知道很多人看過 這篇 文章,里面提到 resource_bundles 不能使用 .xcassets。
那么到底是不是這樣,我們需要親自動手驗證,看看兩種引用方式,CocoaPods 到底為我們做了什么。
我們將在『實際驗證』一節驗證:
resource_bundles
是否能使用 *.xcassets 指定資源並正確打包- 同名沖突是怎樣的
3.1 resource_bundles 是否能使用 *.xcassets 指定資源並正確打包
寫兩個 Demo Pod,同時創建好對應的 Example 測試工程。
對兩個 Pod 分別使用不同的方式指定資源。
第一個 Demo Pod:
第二個 Demo Pod:
分別用了 resource_bundles
和 resources
兩種方式引用。
pod install
后,觀察結果。
3.1.1 使用 resources
pod install
並編譯 Example 工程后,我們可以打開最后生成的 Product 文件下的內容:
可以看到只有 一些 .a
文件,.a
文件是二進制文件。初次之外只有 SubModule-Example.app
,打開包內容,可以看到只有一個 Assets.car
。
這說明,使用 resources
之后只會簡單的將資源文件 copy 到目標工程(Example 工程),最后和目標工程的圖片文件以及其他同樣使用 resources
的 Pod 的圖片文件,統一一起打包為了一個 Assets.car
。
再為 Pod 寫一個 VC 來實驗讀取圖片:
讀取圖片的方式和平常使用的方式不同,要先獲取 Bundle:
UIImage *image = [UIImage imageNamed:@"some-image" |
在 Example 的 ViewController
寫一下跳轉 SubModule/SMViewController
:
運行之后,看一下,能正常訪問圖片:
3.1.2 使用 resource_bundles
pod install
並編譯 Example 工程后,同樣找到 Product 文件下的內容:
可以看到最終生成了一個 SubModule_Use_Bundle.bundle
,打開看內部:
發現包含了一個 Assets.car
再為 Pod 寫一個 VC 來實驗讀取圖片:
由於還需要帶上 .bundle 文件的路徑,獲取的方式又不同:
NSString *bundlePath = [[NSBundle bundleForClass:[self class]].resourcePath |
在 Example 的 ViewController
寫一下跳轉 SubModule/SMViewController
:
運行之后,看一下,也能正常訪問圖片:
3.1.3 resources 和 resource_bundles 對於 .xcassets 的支持
從 3.1 和 3.2 可以看出 resources 和 resource_bundles 都可以很好的支持 .xcassets 的引用。
所以,這篇 文章,里面提到 resource_bundles 不能使用 .xcassets 並不存在。應該說這篇文章已經比較老了,CocoaPods 隨着不斷的更新,resource_bundles
已經可以很好的支持 .xcassets
了。
3.2 同名資源的沖突問題
從上面的分析可以看出:
使用 resources
之后只會簡單的將資源文件 copy 到目標工程(Example 工程),最后和目標工程的圖片文件以及其他同樣使用 resources
的 Pod 的圖片文件,統一一起打包為了一個 Assets.car
。
使用 resource_bundles
之后會為為指定的資源打一個 .bundle
,.bundle
包含一個 Assets.car
,獲取圖片的時候要嚴格指定 .bundle
的位置,很好的隔離了各個庫或者一個庫下的資源包。
顯然,使用 resources
,如果出現同名的圖片,顯然是會出現沖突的,同樣使用 some-image
名稱的兩個圖片資源,不一定能正確調用到。
3.2.1 簡單驗證 resources 重名問題
給 Example 文件添加一個同樣叫 some-image
的圖片:
OK,現在的情況是 Example 工程自己有一個 some-image
圖片資源,SubModule 這個 Pod 庫也有一個 some-image
圖片資源。
還是之前的顯示圖片的代碼,再運行一下:
可以看到,圖片顯然是用錯了,顯示了 Example 工程自己的 some-image
這就是 resources 的重名資源問題。
而使用 resource_bundles
則可以很好的避開這個問題。
4. 總結
resource_bundles 優點:
- 可以使用
.xcassets
指定資源文件 - 可以避免每個庫和主工程之間的同名資源沖突
resource_bundles 缺點:
- 獲取圖片時可能需要使用硬編碼的形式來獲取:
[[NSBundle bundleForClass:[self class]].resourcePath stringByAppendingPathComponent:@"/SubModule_Use_Bundle.bundle"]
resources 優點:
- 可以使用
.xcassets
指定資源文件
resources 缺點:
- 會導致每個庫和主工程之間的同名資源沖突
- 不需要用硬編碼方式獲取圖片:
[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
So,一般來說使用 resource_bundles
會更好,不過關於硬編碼,還可以再找找別的方式去避免。
5. Demo
本文所有的 Demo 代碼都在 這里
有什么問題都可以在博文后面留言,或者微博上私信我,或者郵件我 coderfish@163.com。
博主是 iOS 妹子一枚。
希望大家一起進步。
我的微博:小魚周凌宇
T