在 podspec 中,利用 source_files 可以指定要編譯的源代碼文件。可是,當我們需要把圖片、音頻、NIB等資源打包進 Pod 時該怎么辦呢?
1.如何把資源文件打包為.bundle文件?
通常我們都會用.bundle文件把資源文件打包,這里也一樣,把你的圖片、音頻、NIB等資源文件先統一放在一個文件夾里,文件夾名稱最好是你的組件名稱加上bundle,然后修改文件夾后綴為.bundle,就得到了一個bundle文件;然后把.bundle文件放在與Classes同一級的文件夾下,如下圖
2.如何在podspec文件里配置資源路徑?
然后在podspec文件里通過s.resource指定你的資源文件路徑,如果你的組件名稱叫ICXMeumAssistant,那么你的bundle名稱就可以叫ICXIntelligentAssistantBundle.bundle
在podspec文件里配置:
Pod::Spec.new do |s|
s.name = 'ICXMeumAssistant'
s.version = '0.1.2'
s.summary = '將管家模塊代碼抽取成組件.'
s.description = <<-DESC
TODO: Add long description of the pod here.
DESC
s.homepage = 'https://git.icarbonx.com/ICX-iOS/ICXMeumAssistant'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { ' 呂佳珍' => 'lvjiazhen@icarbonx.com' }
s.source = { :git => 'https://git.icarbonx.com/ICX-iOS/ICXMeumAssistant.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.source_files = 'ICXMeumAssistant/Classes/**/*'
s.resource = 'ICXMeumAssistant/ICXIntelligentAssistantBundle.bundle'
s.dependency 'MJExtension'
s.dependency 'KILabel'
s.dependency 'MJRefresh'
s.dependency 'SDWebImage'
s.dependency 'Masonry'
s.dependency 'ICXPublicMarcoFile'
s.dependency 'ICXPublicCategory'
s.dependency 'ICXPublicTools'
s.dependency 'ICXMBProgressHUDExtension'
s.dependency 'TYAudio2WordsManager'
s.dependency 'ICXUserInfoModule'
s.dependency 'ICXWebViewModule'
s.dependency 'ICX10Clock'
end
3.如何讀取bundle里面的資源?
首先我們需要獲取bundle,你是不是立即想到了NSBundle mainBundle ? 但是當你的 pod 庫以 framework 形式被使用時,你的資源不是被拷貝到 mainBundle 下,而是被放到 pod 的最終產物—— framework里。此時,你必須保證自己在訪問這個 framework 的 bundle,而不是主工程的。
我創建了一個NSBundle的類別文件
先獲取framework 的 bundle,ICXMeumAssistantBundleClass是組件里的一個類文件:
+ (NSURL *)ma_AssistantLibraryBundleURL { //先獲取framework 的 bundle NSBundle *bundle = [NSBundle bundleForClass:[ICXMeumAssistantBundleClass class]]; return [bundle URLForResource:@"ICXIntelligentAssistantBundle" withExtension:@"bundle"]; }
然后再獲取我們自己手動創建的bundle:
+ (instancetype) ma_AssistantBundle { //再獲取我們自己手動創建的bundle return [self bundleWithURL:[self ma_AssistantLibraryBundleURL]]; }
獲取到了我們存放資源文件的bundle文件以后,就可以訪問資源文件了,比如獲取名為imageName的圖片:
+ (UIImage *)ma_AssistantImageNamed:(NSString *)imageName { UIImage *loadingImage = [[UIImage imageWithContentsOfFile:[[self ma_AssistantBundle] pathForResource:[NSString stringWithFormat:@"%@@2x",imageName] ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; return loadingImage; }
加載xib文件需要注意的是當你只是把xib文件放到.bundle文件里的話,那么加載xib文件就會一直報異常:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/adminuser/Library/Developer/CoreSimulator/Devices/464AB3F8-3C31-4473-AD1B-F554F3F59CDB/data/Containers/Bundle/Application/B4A5F964-A6E0-4357-878F-11A299FD1ACA/MyTestApp.app> (loaded)' with name 'TPDoctorIntroductionView
'
這是因為.bundle文件里只放了xib文件,並沒有nib文件,需要進行一下轉化:
在終端輸入以下命令進行轉化:
ibtool --errors --warnings --output-format human-readable-text --compile TPDoctorIntroductionView.nib TPDoctorIntroductionView.xib
如果提示你Xcode路徑不對的話,再重置一下你的Xcode路徑:
sudo xcode-select -switch /Applications/Xcode9.3.app/Contents/Developer
轉化以后,路徑下就多了同名的nib文件,但我目前不知道如果有多個xib怎么能通過一句命令全部生成nib
然后加載xib文件就不會異常啦
+ (instancetype)doctorView{ return [[NSBundle ma_AssistantBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil][0]; }
加載國際化文件
+ (NSString *)ma_AssistantLocalizedStringForKey:(NSString *)key { return [self ma_AssistantLocalizedStringForKey:key value:nil]; } + (NSString *)ma_AssistantLocalizedStringForKey:(NSString *)key value:(NSString *)value { static NSBundle *bundle = nil; if (bundle == nil) { // (iOS獲取的語言字符串比較不穩定)目前框架只處理en、zh-Hans、zh-Hant三種情況,其他按照系統默認處理 NSString *language = [NSLocale preferredLanguages].firstObject; if ([language hasPrefix:@"en"]) { language = @"en"; } else if ([language hasPrefix:@"zh"]) { if ([language rangeOfString:@"Hans"].location != NSNotFound) { language = @"zh-Hans"; // 簡體中文 } else { // zh-Hant\zh-HK\zh-TW language = @"zh-Hant"; // 繁體中文 } } else { language = @"en"; } // 從.bundle中查找資源 bundle = [NSBundle bundleWithPath:[[NSBundle ma_AssistantBundle] pathForResource:language ofType:@"lproj"]]; } value = [bundle localizedStringForKey:key value:value table:nil]; return value; }
PS:這里說的只是我個人習慣用的一種方式,其實還可以使用resource_bundles的方式,但道理都是相同的,盡可能避免跟主工程訪問沖突