上篇文章中提到我們目前的工程用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];
}
}