背景
目前项目App包体积较大,分析项目中图片资源占据比例较大,首先从图片方面进行优化。
1.图片集成方式
现状:目前pod库中图片直接存放在bundle下,存在@2x,@3x图,通过bundle去访问图片资源。
这样会造成安装的设备中同时存在@2x和@3x的图片。
如果使用Asset Catlogs去管理图片,即下图使用.xcasset的形式,xcassets 里面的 @2x、@3x 会根据具体设备分发,只包含符合目标设备分辨率的图片,不会同时包含,以此来缩小用户下载的包体积。(App Slicing)
以下为实验结果:
结论:使用Asset catalogs取代Bundle管理图片的形式
2.图片资源引用方式
使用Asset catalogs管理图片资源来取代Bundle管理图片的形式,包体积会减少,那么我们在使用时也需要注意以下问题
2.1 图片资源冲突
经过打包测试,在静态库中Asset catalogs管理的图片资源是与主工程Asset catalogs管理的图片资源统一生成为一个Asset.car的文件,所以其中有可能存在图片冲突的问题。
如果两个图片名称一致,但是图片是不一样的内容,那么就会存在加载错图片的问题。所以在静态库中使用Asset catalogs要格外注意。
2.2 图片管理方式分析
那么pod库中,我们改通过何种方式去管理图片资源,有各有什么优缺点,以下进行了整理
— |
图片管理方式 |
引用方式 |
分析 |
使用建议 |
静态库 |
Bundle |
resources |
同时存在@2x和@3x的图片 |
❌ |
|
静态库 |
Bundle |
resource_bundle |
同时存在@2x和@3x的图片 |
❌ |
静态库 |
Asset catalogs |
resources |
仅包含一种分辨率图片,但有可能与主工程图片资源冲突 |
❌ |
静态库 |
Asset catalogs |
resource_bundle |
仅包含一种分辨率图片,且不会有冲突 |
✔️ |
动态库 |
Bundle |
resources |
同时存在@2x和@3x的图片 |
❌ |
动态库 |
Bundle |
resource_bundle |
会造成bundle中嵌套bundle |
❌ |
动态库 |
Asset catalogs |
resources |
仅包含一种分辨率图片 |
✔️ |
动态库 |
Asset catalogs |
resource_bundle |
仅包含一种分辨率图片,由于动态库本身图片资源是在自身framework中,不存在与其他pod库资源冲突的问题 |
✔️ |
关于resources 与 resource_bundle的区别在于:
resource_bundles 允许定义当前 Pod 库的资源包的名称和文件。用 hash 的形式来声明,key 是 bundle 的名称,value 是需要包括的文件的通配 patterns。
CocoaPods 官方强烈推荐使用 resource_bundles,因为用 key-value 可以避免相同名称资源的名称冲突。
使用 resources 来指定资源,被指定的资源只会简单的被 copy 到目标工程中(主工程),所以存在资源冲突的问题。
2.3 如何调用
使用resource_bundle调用图片的方式与使用resources的有所不同:
1 2 3 4 5 6 7
| let currentBundle = Bundle.init(for: ShowBundleIconController.self) let bundle = Bundle(url: currentBundle.url(forResource: "IconBundleModule", withExtension: "bundle")!) let image = UIImage(named: "es8_pearlwhite_side", in: bundle, compatibleWith: nil) let imageView = UIImageView(frame: CGRect(x: 0, y: 100, width: 200, height: 100)) imageView.image = image view.addSubview(imageView)
|
3.IconFont
针对于单色的图标,我们也可以用IconFont来管理:
1.以tff的形式来管理图片,减少体积
2.以阿里IconFont为例,生成tff文件所上传的svg限制单个大小为40KB
3.在iOS项目中不支持多色的使用
4.使用方式
以下为几种使用方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| // ----------------------------- 未封装前用法 使用UILabel去展示 -------------------------------------------- let label = UILabel(frame: CGRect(x: 30, y: 100, width: 50, height: 50)) label.font = UIFont.init(name: "iconfont", size: 50) label.text = "\u{e604}" view.addSubview(label) // ----------------------------- EFIConFont 使用UILabel去展示 -------------------------------------------- let iconlabel = UILabel(frame: CGRect(x: 30, y: 170, width: 50, height: 50)) iconlabel.font = EFIconFont.antDesign.cake.font(size: 50) iconlabel.text = EFIconFont.antDesign.cake.unicode iconlabel.textAlignment = .right view.addSubview(iconlabel)
// ----------------------------- EFIConFont 使用UIImageView去展示 -------------------------------------------- let iconImgView = UIImageView(frame: CGRect(x: 30, y: 240, width: 50, height: 50)) iconImgView.image = EFIconFont.antDesign.dessert.image(size: iconImgView.frame.size) view.addSubview(iconImgView) // ----------------------------- EFIConFont 使用UIImageView去展示 -------------------------------------------- let iconImgView1 = UIImageView(frame: CGRect(x: 100, y: 240, width: 50, height: 50)) iconImgView1.image = EFIconFont.antDesign.dessert.image(size: iconImgView1.frame.size, foregroundColor: UIColor.red) view.addSubview(iconImgView1) // ----------------------------- EFIConFont 使用富文本去展示 -------------------------------------------- let iconAttributeLbl = UILabel(frame: CGRect(x: 30, y: 300, width: 50, height: 50)) iconAttributeLbl.attributedText = EFIconFont.antDesign.dessert.attributedString(size: 50) iconAttributeLbl.textAlignment = .right view.addSubview(iconAttributeLbl)
|
总结
1.采用Assets catalogs来代替 Bundle管理的资源
2.对于单色的简单图标,可以采用IconFont,但减少体积有限,且替换成本较高。