iOS 中 Pod 库资源引用探究

👇👇关注后回复 “进群” ,拉你进程序员交流群👇👇

前言

CocoapodsPod引用资源的方式有多种,不同的方式对资源的使用还是有区别的,但也有一定的规律,这里我用一个样例工程来进行说明,样例工程名叫:AssetsDemo,使用pod lib create AssetsDemo命令创建,目录结构如图:

outside_default.png

这个pod很简单,Classes目录只有一个cellswiftxib文件,Assets目录有一些图片资源,其中的TestTableViewCell.xib使用了这张test图片。目录结构如下:

├── Assets
│   ├── Images.xcassets
│   │   ├── Contents.json
│   │   └── test.imageset
│   │       ├── Contents.json
│   │       ├── test@2x.png
│   │       └── test@3x.png
│   ├── test1@2x.png
│   └── test1@3x.png
└── Classes
    ├── TestTableViewCell.swift
    └── TestTableViewCell.xib

前期工作已经准备完毕,下面说下xib图片资源不同使用方式下的区别:

xib放入source_files,图片放入resource_bundles

podspec的写法如下:

s.source_files = 'AssetsDemo/Classes/**/*'
s.resource_bundles = {
    'AssetsDemo' => ['AssetsDemo/{Assets,Classes}/**/*.{xcassets,png}']
}

运行后会生成这样的framework

outside_default.png

我们可以看到,xib后缀会变成nib,并被放入framework中,而图片资源被放入了AssetsDemo.bundle中。

这样的结构,显然在常规情况下,xib是没法找到图片并显示的。但是有一种有缺陷的用法可以勉强解决这个问题,那就是直接把png图片打包到AssetsDemo.bundle中,然后在xib中将图片名改为AssetsDemo.bundle/图片名。这样做会导致xib编辑时无法正确的显示图片,也没法使用xcassets目录来存储图片,并且会导致一些系统优化无法生效。不推荐这样使用。

xib图片都放入resources

podspec的写法如下:

s.source_files = 'AssetsDemo/Classes/**/*.swift'
s.resources = 'AssetsDemo/{Assets,Classes}/**/*.{xcassets,png,xib}'

网上有说法使用resources来指定资源,被指定的资源只会简单的被 copy到目标工程中(主工程),资源的使用会简化,但是会与主工程同名资源文件产生冲突。但是在Xcode13pod 1.11.2版本下,实测不是这样的。官方的文档也不是这样说的Podspec Syntax Reference v1.11.2[1],它是分静态库和动态库场景,静态库才有这类问题。

上述配置运行后会生成这样的framework结构:

outside_default.png

从上图可以看到,资源被直接放入了所在的framework,另外查看主工程的包文件,是没有这些资源的。综上所述,可以得出结论,动态库中,resources指定的资源,会被直接copyframework,不会与主工程资源文件冲突。

另外,由于xib文件TestTableViewCell.nibAssets.car在同一个目录下,xib可以直接从Assets.car中找到图片资源并正确展示

  1. 在主工程中打开这个xib文件,如果主工程中有同名资源,那么编辑时会优先显示主工程的资源,但是实际运行时还是这个pod的资源。

  2. 这里xib可以放入source_filesresources,效果是一样的

xib图片都放入resource_bundles

podspec的写法如下:

s.source_files = 'AssetsDemo/Classes/**/*.swift'
s.resource_bundles = {
    'AssetsDemo' => ['AssetsDemo/{Assets,Classes}/**/*.{xcassets,png,xib}']
}

上述配置运行后会生成这样的framework结构:

outside_default.png

从上图可以看到,xib文件TestTableViewCell.nibAssets.car在同一个目录下,xib可以直接从Assets.car中找到图片资源并正确展示。其中,test1图片虽然没有以xcassets格式引入,但是也能直接找到并正确展示。

总结

综上所述,我们可以得出一个原则:尽量让xibxcassets与图片在同一个目录下,这样xib可以直接找到图片并正常展示。

关于resourcesresource_bundles,在动态库下,他们最终效果差不多,只是resource_bundles会把资源封装在bundle中,使用的时候会稍微麻烦一点:

// 使用resources的情况:
let myBundle = Bundle(for: TestTableViewCell.self)
tableView.register(UINib.init(nibName: "TestTableViewCell", bundle: myBundle),
                    forCellReuseIdentifier: "cell")

// 使用resource_bundles的情况:
let myBundle = Bundle(for: TestTableViewCell.self)
let path = myBundle.path(forResource: "AssetsDemo", ofType: "bundle")!
let assetsBundle = Bundle.init(path: path) 
tableView.register(UINib.init(nibName: "TestTableViewCell", bundle: assetsBundle),
                    forCellReuseIdentifier: "cell")

至于静态库,则推荐使用resource_bundles了。综合来看,不管是静态库还是动态库,都推荐使用resource_bundles来引入所有的资源,因为resources方式在静态库和动态库场景,资源的使用方法差异太大,而resource_bundles各场景是一致的。

至于source_files,它只能引入代码和xib文件,不支持引入图片等其它资源。不建议用source_files方式引入xib,如果一定要使用,要注意避免出现xib中图片无法加载的问题。

参考资料

  • Podspec Syntax Reference v1.11.2[2]

  • 关于 Pod 库的资源引用 resource_bundles or resources[3]

参考资料

[1]

Podspec Syntax Reference v1.11.2: https://guides.cocoapods.org/syntax/podspec.html#resources

[2]

Podspec Syntax Reference v1.11.2: https://guides.cocoapods.org/syntax/podspec.html#specification

[3]

关于 Pod 库的资源引用 resource_bundles or resources: https://juejin.cn/post/6844903559931117581#heading-2

by: 掘金 - 星的天空 

https://juejin.cn/post/7063314733415268366

-End-

最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!

bba5dc5a38b065389273739a268eca82.png

点击👆卡片,关注后回复【面试题】即可获取

在看点这里999b01a50c043d4802055d4603aedcdd.gif好文分享给更多人↓↓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值