前言
制作本地本地POD
库就不做过多的介绍,因为本身就一个命令的事pod lib create xxxx
用pod
管理项目的时候,如果用到了图片或者XIB
文件一般有两种写法:resources
或者resource_bundles
Example
spec.resources = "CXSalesmanModule/**/*.{xib,png}"
spec.resource_bundles = {
'CXSalesmanModule' => ['CXSalesmanModule/**/*.{xib,png,xcassets}']
}
先来说说区别:
- 利用
resources
属性可以指定pod
要使用的资源文件。这些资源文件在build
时会被直接拷贝到client target
的mainBundle
里。这样就实现了把图片、音频、NIB
等资源打包进最终应用程序的目的。但是这会导致POD
库的资源文件和主工程里的资源文件命名冲突。
Example
主工程有一个
a.png
的图片,而pod
库里面也有一个a.png
的图片,此时就产生命名冲突了。
-
resource_bundles
就是为了解决命名冲突的问题,CocoaPods
在0.23.0
加入的新属性。 -
resource_bundles
会自动生成bundle
把资源文件打包进去,resources
则不会。所以我们在使用resources
的时候一般都会把资源文件提前打包到bundle
最后在添加。
建议使用
resource_bundles
方式来管理资源文件
use_frameworks
重点
OC
项目pod init
的时候一般是不使用use_frameworks!
,但是当我们用cocoapods
导入swift
框架到swift
项目和OC
项目都必须要use_frameworks!
对于Podfile
有或者没有使use_frameworks
;resources
或者resource_bundles
这两种写法的最后编译之后生成的包是不一样的。
- 如果使用了
use_frameworks
编译之后查看包,我们会发现POD
库是放在mainBundle
下的Frameworks
目录下。 - 没有使用
use_frameworks
,则不会生成Frameworks
。
pod install
编译之后我们来看下资源文件打包到哪里了
使用spec.resources
写法
spec.resources = ["CXSalesmanModule/**/*.{xib,png}"]
没有使用user_frameworks
如果使用图片或者XIB
,因为资源文件是直接打包到和主工程的bundle
也就是mainBundle
,所以我们依旧可以和之前的写法一样:
使用
self.imagView.image = [UIImage imageNamed:@"icon_mine_grade"];
// xib 这里暂未做测试
使用了user_frameworks
此时我们发现pod
库里面的资源文件被打包进了主工程(即:mainBundle
)下的Frameworks->CXSalesmanModule.framework
目录下:
所以我们使用资源文件的时候,就不能直接加载mainBundle
;我们需要找到资源文件所在的bundle
获取bundle
的两种方式
通过class
类型查找对应的bundle
目录,这种在category
中不能使用,虽然可以通过传入class
的方式查找,但是容易出错。不建议使用
NSBundle *cbundle = [NSBundle bundleForClass:[self class]];
NSString *path = [bundle pathForResource:bundleName ofType:@"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:path];
使用
NSURL *associateBundleURL = [[NSBundle mainBundle] URLForResource:@"Frameworks" withExtension:nil];
associateBundleURL = [associateBundleURL URLByAppendingPathComponent:@"CXSalesmanModule"];
associateBundleURL = [associateBundleURL URLByAppendingPathExtension:@"framework"];
NSBundle *bundle = [NSBundle bundleWithURL:associateBundleURL];
self.imagView.image = [UIImage imageNamed:@"icon_mine_grade"
inBundle: associateBunle
compatibleWithTraitCollection:nil];
XIB
同理也是通过Bundle
去加载。
使用spec.resource_bundles
写法
spec.resource_bundles = {
'CXSalesmanModule' => ['CXSalesmanModule/**/*.{xib,png,xcassets}']
}
没有使用user_frameworks
此时我们发现pod
库里面的资源文件是被打包进了主工程(即:mainBundle
)里面的CXSalesmanModule.bundle
内,所以我们使用的话,只需要拿到这个bundle
即可。这里也验证了上面所说的resource_bundles
会默认生成bundle
使用
NSURL *url = [[NSBundle mainBundle] URLForResource:@"CXSalesmanModule" withExtension:@"bundle"];
NSBundle *bundle = [NSBundle bundleWithURL:url];
self.imagView.image = [UIImage imageNamed:@"icon_mine_grade"
inBundle: bundle
compatibleWithTraitCollection:nil];
使用了user_frameworks
此时我们发现pod
库里面的资源文件是被打包进了主工程(即:mainBundle
)下的Frameworks->CXSalesmanModule.framework->CXSalesmanModule.bundle
目录下:
所以我们使用资源文件的时候,就不能直接加载mainBundle
;我们需要找到资源文件所在的CXSalesmanModule.bundle
,这里也验证了上面所说的resource_bundles
会默认生成bundle
使用
NSURL *associateBundleURL = [[NSBundle mainBundle] URLForResource:@"Frameworks" withExtension:nil];
associateBundleURL = [associateBundleURL URLByAppendingPathComponent:@"CXSalesmanModule"];
associateBundleURL = [associateBundleURL URLByAppendingPathExtension:@"framework"];
NSBundle *associateBunle = [NSBundle bundleWithURL:associateBundleURL];
associateBundleURL = [associateBunle URLForResource:@"CXSalesmanModule" withExtension:@"bundle"];
NSBundle *bundle = [NSBundle bundleWithURL:associateBundleURL];
self.imagView.image = [UIImage imageNamed:@"icon_mine_grade"
inBundle: bundle
compatibleWithTraitCollection:nil];
XIB
同理也是通过Bundle
去加载。
总的来说,使用
pod
库里面的资源文件,我们只需要找资源文件所在的路径即可,如果是mainBundle
则使用方式不变,如果是其他的bundle
,我们只要获取到bundle
就可以通过bundle
去使用。
图片存放方式
- 直接将
png
格式的图片拖到Assets
目录下。 - 采用
xcassets
,将图片都放到Images.xcassets
里面,新建项目的时候默认工程会有一个Assets.xcassets
。
这里的图片是采用xcassets
来打包的,按住command
+ n
选择Asset Catalog
即可。
一般我们都是直接把图片放到相应的目录下,这里我要说的是resource_bundles
打包图片使用xcassets
的注意点
注意(低于iOS10
的系统)
对于pod
资源打包方式采用resource_bundles
并且podfile
里使用了user_framework
,如果采用.xcassets
方式打包图片,iOS9 Release
环境下图片会加载不出来。如果未使用user_framework
则可以正常展示(iOS8
暂没有测试,以及采用resources
来打包这里本人暂未做测试有兴趣的小伙伴可以去测试一波)