通過 Method swizzing解決項目模塊化後語言國際化的問題

上篇文章中提到我們目前的工程用pod進行了模塊化管理,當項目被拆分之後,資源文件、語言文件當然也要被拆分。

因爲一開始以爲和圖片資源一樣,不用特殊處理,最終會合併爲一個car文件。拆分的時候就直接在每個模塊下面建立一個語言文件,命名爲:Localizable.strings。拆好一個模塊之後,run起來發現大量的翻譯丟失了,仔細檢查之後發現,工程中的string文件並沒有像想象中的那樣合併起來,而是隻打包了一份string文件進來,那這個問題就尷尬了,因爲之前都是用的

NSLocalizedString(@"login_fail",@"登錄失敗"); 

這樣的方式來進行翻譯的,沒有指定string的文件名,如果要改數量就比較巨大了。是時候祭出 Method swizzing,解決這一難題了。

首先第一步:檢查NSLocalizedString這個宏定義對應的方法

[NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:nil]
在哪些地方使用,交換之後會不會影響第三方庫的語言問題。檢查後發現項目中所使用的第三方庫都是用bundle打包了自己的資源文件,不會用這個方法進行加載語言文件。 Method swizzing 是可以放心的用了。

第二步,將剛剛拆出來的文件重新命名,重新編譯之後,解壓發現.app中確實有了兩個string文件。這一步也成功了

第三步,進行方法交換。上代碼:

#import "NSBundle+ZATool.h"
#import <objc/runtime.h>
@implementation NSBundle (ZATool)

+(void)load
{
  
    //需要交換的系統方法,類方法和對象方法使用的方法不同
    Method  fromMethod = class_getInstanceMethod([self class], @selector(localizedStringForKey:value:table:));
    //需要交換的自己寫的方法
    Method  toMethod = class_getInstanceMethod([self class], @selector(ZALocalizedStringForKey:value:table:));
    //方法交換
    method_exchangeImplementations(fromMethod, toMethod);
}

#pragma mark - 多語言方法實現
-(NSString *)ZALocalizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
    //語言文件數組
    NSArray *array=@[@"CommonLocalizable",@"Localizable"];

    
    if (!tableName || [array containsObject:tableName]) {
        if (!tableName) {
            tableName=@"CommonLocalizable";
        }
        //注意:方法交換是相互交換的,這裏相當於是調的系統的翻譯方法
        NSString *string= [self ZALocalizedStringForKey:key value:value table:tableName];

        if ([string isEqualToString:key]) {
            //當取不到翻譯字符串的時候,遞歸調用從下一個翻譯文件中查找
            NSInteger tag=[array indexOfObject:tableName];
            
            if (tag!=array.count-1) {
 
                tableName=array[tag+1];
                //注意:方法交換是相互交換的,這裏相當於是調的我們自己的翻譯方法
                string= [self localizedStringForKey:key value:value table:tableName];
            }
        }else{
        }
        
        return string;
    
    }else
    {
        return  [self ZALocalizedStringForKey:key value:value table:tableName];
    }
  
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章