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意義一樣,所以不用提前在主工程中添加~
暫時理解這么多
出問題代碼