动态库和静态库之二:引用资源文件

一、新建Bundle

示例是在主工程SwiftTest的子工程Home里进行。

因为iOS框架中没有Bundle,所以要在macOS中创建Bundle。

新建Bundle.png

二、往Bundle中添加资源

将资源文件(如图片、xib文件)拖入刚创建的Bundle文件夹下。新创建xib时可以直接创建到Bundle文件夹目录下。

给Bundle添加资源.png
添加完资源示例.png

三、配置Bundle

1.修改Base SDK为iOS

修改Base SDK.png

2.iOS Deployment Target改为需要支持的最低版本

修改Deployment版本.png

注意:
可以不用修改Deployment版本,但是不修改的话,后续如果使用手动编译、且在真机上进行编译,则可能会报Deployment Target不匹配的错。


真机编译Bundle时Deployment Target不匹配报错.png

3.Enable Bitcode设置为No,其中只放资源文件,否则编译会报错

设置Enable Bitcode.png

Enable Bitcode未设置为No报错.png
  1. COMBINE_HIDPI_IMAGES设置为NO
    iOS 创建Bundle时放入的图片资源(.png)在默认配置下会被转为.tiff格式,使用的时候找不到。因为在iOS中创建bundle时会用一个“hack”,为了使所有的运行需要更改一个配置。找到bundle的工程,Buld Settings > COMBINE_HIDPI_IMAGES设置为NO
修改COMBINE_HIDPI_IMAGES.png

COMBINE_HIDPI_IMAGES为YES时打包后成果.png

COMBINE_HIDPI_IMAGES为NO时打包后成果.png

四、编译Bundle

在Scheme中选择Bundle作为target、设备选Any iOS Device或者具体真机进行编译,不先编译的话,使用的时候会报错。

编译Bundle.png

未编译就使用报错.png

注意:

  • 如果动态库Target的Dependencies中设置了Bundle依赖,则可不手动提前编译Bundle。

五、使用Bundle里的资源文件

1.在动态库Target的Copy Bundle Resources、Dependencies中添加Bundle。

引用Bundle.png

注意:

  • 必须在Dependencies (图中3.1)中也添加一下Bundle依赖,否则会出现编译运行不报错,打包报错的问题。
未设置Dependencies依赖打包报错.png

2.使用xib

let bundle = Bundle(for: HomeViewController.self)
// 加载方式1:如果未在Copy Bundle Resources中引用Bundle时会出现crash现象
let nibs1 = bundle.loadNibNamed("HomeResource.bundle/ToolBar", owner: nil, options: nil)
// 加载方式2:推荐使用
guard let resourceURL = bundle.url(forResource: "HomeResource", withExtension: "bundle") else { return }
let nibs2 = Bundle(url: resourceURL)?.loadNibNamed("ToolBar", owner: nil, options: nil)
// 读取xib中视图并展示
if let xibView = nibs?.first as? UIView {
    xibView.frame = CGRect(x: 20, y: 180, width: 250, height: 44)
    view.addSubview(xibView)
}

3.使用图片

let imageView = UIImageView(frame: CGRect(x: 100, y: 100, width: 80, height: 80))
let bundle = Bundle(for: HomeViewController.self)
// 加载方式1
imageView.image = UIImage(named: "HomeResource.bundle/load_failure", in: bundle, compatibleWith: nil)
// 加载方式2
guard let resourceURL = bundle.url(forResource: "HomeResource", withExtension: "bundle") else { return }
imageView.image = UIImage(named: "load_failure", in: Bundle(url: resourceURL), compatibleWith: nil)

六、修改资源文件后的处理

  • 通常情况下(动态库Target未在Dependencies中设置Bundle依赖试),Bundle中资源文件有修改时,需重新编译Bundle,其使用方(动态库)才能读取修改后的资源。
  • 在动态库Target的Dependencies中添加对Bundle的依赖,则每次编译动态库时也会自动编译Bundle,从而能随时读取Bundle中资源的更新。
Dependencies中设置Bundle依赖.png

推荐阅读更多精彩内容