1、使用macOS创建一个.bundle工程.png
2、工程名字为生成boudle的名称.png
3、修改工程配置
3.1
"Base SDK" 设置为 "Latest iOS (iOS 11.2)" (Xcode 9.2为例)
"Build Active Architecture Only" 设置为 "YES"
3.1 修改一.png
3.2 修改二.png
4770884-d5db088986bad142.png
4770884-232f7087f75c8f63.png
4770884-ddbb884d15560ae6.png
4770884-25fb96fed2fb09b5.png
[图片上传中...(4770884-25fb96fed2fb09b5.png-abd0a1-1563864788941-0)]
4770884-2cd27c712ada01c2.png
取出
4770884-da507b5cf7e8f1f1.png
- 将要使用的bundle集成到项目中后,就可以使用了。需要注意的就是,bundle是静态的,不进行编译的资源文件。所以,要使用bundle中的资源,就需要找到相应的资源路径。VC获得bundle中的资源
方法一:
UIImage *image = [UIImage imageNamed:@"JZYConferenceUIResource.bundle/back_guide_bar"];
备注: (直接把.boudle放在工程中是可以通过这种方式获取)
image.png
方法二:(直接把.boudle放在工程中 无效)
NSString *bundlePath = [[ NSBundle mainBundle] pathForResource:@"JZYConferenceUIResource" ofType :@"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
NSString *img_path = [bundle pathForResource:@"back_guide_bar" ofType:@"png"];
UIImage *image_1=[UIImage imageWithContentsOfFile:img_path];
image.png
方法三:(本人使用的方式 因为本人是开发sdk,所以图片资源直接放在库中,外面工程感知不到,参考QMUIKit库的方式写的。)
.m
// MARK:- loazing '.boudle' Image for sdk
+ (UIImage *)imageWithName:(NSString *)name {
NSBundle *bundle = [JZYHelperManager resourcesBundleWithName:@"JZYConferenceUIResource.bundle"];
return [JZYHelperManager imageInBundle:bundle withName:name];
}
+ (UIImage *)imageInBundle:(NSBundle *)bundle withName:(NSString *)name {
if (bundle && name) {
if ([UIImage respondsToSelector:@selector(imageNamed:inBundle:compatibleWithTraitCollection:)]) {
return [UIImage imageNamed:name inBundle:bundle compatibleWithTraitCollection:nil];
} else {
NSString *imagePath = [[bundle resourcePath] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", name]];
return [UIImage imageWithContentsOfFile:imagePath];
}
}
return nil;
}
+ (NSBundle *)resourcesBundleWithName:(NSString *)bundleName {
NSBundle *bundle = [NSBundle bundleWithPath: [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:bundleName]];
if (!bundle) {
// 动态framework的bundle资源是打包在framework里面的,所以无法通过mainBundle拿到资源,只能通过其他方法来获取bundle资源。
NSBundle *frameworkBundle = [NSBundle bundleForClass:[self class]];
NSDictionary *bundleData = [JZYHelperManager parseBundleName:bundleName];
if (bundleData) {
bundle = [NSBundle bundleWithPath:[frameworkBundle pathForResource:[bundleData objectForKey:@"name"] ofType:[bundleData objectForKey:@"type"]]];
}
}
return bundle;
}
+ (NSDictionary *)parseBundleName:(NSString *)bundleName {
NSArray *bundleData = [bundleName componentsSeparatedByString:@"."];
if (bundleData.count == 2) {
return @{@"name":bundleData[0], @"type":bundleData[1]};
}
return nil;
}
.h
/**
设置图标 通过.boudle文件
@param name 图标名称
@return UIImage
*/
+ (UIImage *)imageWithName:(NSString *)name;
使用 imageWithName直接传图片名,注意⚠️ ‘resourcesBundleWithName:’ 方法换成你自己的.boudle名字哦~
- 如果将自己打包的bundle给别人使用,别人在打包上传过程中可能会遇到错误提示如:
ERROR ITMS-90171: "Invalid Bundle Structure - The binary file 'lhby.app/Test.bundle/Test' is not permitted. Your app can’t contain standalone executables or libraries, other than a valid CFBundleExecutable of supported bundles. Refer to the Bundle Programming Guide at...或者ERROR ITMS-90535: "Unexpected CFBundleExecutable Key. The bundle at 'Payload/dianlan2.app/EaseUIResource.bundle' does not contain a bundle executable. If this bundle intentionally does not contain an executable, consider removing the CFBundleExecutable key from its Info.plist and using a CFBundlePackageType of BNDL. If this bundle is part of a third-party framework, consider contacting the developer of the framework for an update to address this issue."或者ERROR ITMS-90034: "Missing or invalid signature. The bundle 'ABC.Test' at bundle path 'Payload/lhby.app/Test.bundle' is not signed using an Apple submission certificate."
网上也有很多的解决办法,这里提供一种解决方法,就是删除bundle里的执行文件:找到工程中的Test.Bundle,右键单击后 选择 "显示包内容",找到里面黑色的可执行文件Test,删除掉,然后找到里面的info.plist文件 ,删除掉Executable file 字段,重新打包,上传应用商店就可以了。
备注:因为类似文章不少,直接盗用的图,知者勿怪,不知更好,只为更清晰的呈现
补充:
在静态库sdk开发中,发现由于[NSBundle bundleForClass:[self class]] 路径问题照成bundle为nil;
解决方案:如果是静态库,需要在主工程中添加下这个.boudle文件才能获取正确路径;
分析:动态库sdk在程序启动时已经把库进行加载了所以和静态库提前添加.boudle意义一样,所以不用提前在主工程中添加~
暂时理解这么多
出问题代码