前言
制作本地本地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来打包这里本人暂未做测试有兴趣的小伙伴可以去测试一波)