关于 Pod 库的资源引用 resource_bundles or resources

1. 资源文件引用的方式

在第一节,先来介绍一下 CocoaPods 两种资源文件引用的方式——resource_bundles & resourceshtml

1.1 resource_bundles

resource_bundles 容许定义当前 Pod 库的资源包的名称和文件。用 hash 的形式来声明,key 是 bundle 的名称,value 是须要包括的文件的通配 patterns。ios

We strongly recommend library developers to adopt resource bundles as there can be name collisions using the resources attribute.git

CocoaPods 官方强烈推荐使用 resource_bundles,由于用 key-value 能够避免相同名称资源的名称冲突。github

同时建议 bundle 的名称至少应该包括 Pod 库的名称,能够尽可能减小同名冲突xcode

Examples:ruby

spec.ios.resource_bundle = { 'MapBox' => 'MapView/Map/Resources/*.png' }
复制代码
spec.resource_bundles = {
    'MapBox' => ['MapView/Map/Resources/*.png'],
    'OtherResources' => ['MapView/Map/OtherResources/*.png']
  }
复制代码

1.2 resources

使用 resources 来指定资源,被指定的资源只会简单的被 copy 到目标工程中(主工程)。app

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.ide

官方认为用 resources 是没法避免同名资源文件的冲突的,同时,Xcode 也不会对这些资源作优化。测试

Examples:优化

spec.resource = 'Resources/HockeySDK.bundle'
复制代码
spec.resources = ['Images/*.png', 'Sounds/*']
复制代码

FYI: Podspec Syntax Reference v1.4.0

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 到底为咱们作了什么。

咱们将在『实际验证』一节验证:

  1. resource_bundles 是否能使用 *.xcassets 指定资源并正确打包
  2. 同名冲突是怎样的

3.1 resource_bundles 是否能使用 *.xcassets 指定资源并正确打包

写两个 Demo Pod,同时建立好对应的 Example 测试工程。

对两个 Pod 分别使用不一样的方式指定资源。

第一个 Demo Pod:

第二个 Demo Pod:

分别用了 resource_bundlesresources 两种方式引用。

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"
                                inBundle:[NSBundle bundleForClass:[self class]]
           compatibleWithTraitCollection:nil];
复制代码

在 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
                            stringByAppendingPathComponent:@"/SubModule_Use_Bundle.bundle"];
NSBundle *resource_bundle = [NSBundle bundleWithPath:bundlePath];
UIImage *image = [UIImage imageNamed:@"some-image"
                                inBundle:resource_bundle
           compatibleWithTraitCollection:nil];
复制代码

在 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 优势:

  1. 可使用 .xcassets 指定资源文件
  2. 能够避免每一个库和主工程之间的同名资源冲突

resource_bundles 缺点:

  1. 获取图片时可能须要使用硬编码的形式来获取:[[NSBundle bundleForClass:[self class]].resourcePath stringByAppendingPathComponent:@"/SubModule_Use_Bundle.bundle"]

resources 优势:

  1. 可使用 .xcassets 指定资源文件

resources 缺点:

  1. 会致使每一个库和主工程之间的同名资源冲突
  2. 不须要用硬编码方式获取图片:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];

So,通常来讲使用 resource_bundles 会更好,不过关于硬编码,还能够再找找别的方式去避免。

5. Demo

本文全部的 Demo 代码都在 这里


有什么问题均可以在博文后面留言,或者微博上私信我,或者邮件我 coderfish@163.com

博主是 iOS 妹子一枚。

但愿你们一块儿进步。

个人微博:小鱼周凌宇

相关文章
相关标签/搜索