iOS組件化之-給自己的組件添加資源文件


在 podspec 中,利用 source_files 可以指定要編譯的源代碼文件。可是,當我們需要把圖片、音頻、NIB等資源打包進 Pod 時該怎么辦呢?

 1.如何把資源文件打包為.bundle文件?

通常我們都會用.bundle文件把資源文件打包,這里也一樣,把你的圖片、音頻、NIB等資源文件先統一放在一個文件夾里,文件夾名稱最好是你的組件名稱加上bundle,然后修改文件夾后綴為.bundle,就得到了一個bundle文件;然后把.bundle文件放在與Classes同一級的文件夾下,如下圖

 2.如何在podspec文件里配置資源路徑?

然后在podspec文件里通過s.resource指定你的資源文件路徑,如果你的組件名稱叫ICXMeumAssistant,那么你的bundle名稱就可以叫ICXIntelligentAssistantBundle.bundle

在podspec文件里配置:

  s.resource     = 'ICXMeumAssistant/ICXIntelligentAssistantBundle.bundle'
 
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的方式,但道理都是相同的,盡可能避免跟主工程訪問沖 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM