iOS 國際化

一、如何建立 Localized.strings 文件

可以參考這篇文章,比較詳細(xì)

二枷恕、使用 genstrings 自動生成 key-value

genstrings [-a] [-q] [-o <outputDir>] sourcefile  

其中參數(shù):
-a 在存在的文件后面追加內(nèi)容
-q 關(guān)閉多個鍵/值對的警告
-o 指定輸出目錄

因此如果我們想輸出到en.lproj目錄,則代碼如下:

genstrings -o en.lproj  *.m

遍歷 子目錄:

find ./ -name *.m -print0 | xargs -0 genstrings -o (en.lproj目錄)
find ./ -name '*.m' -print0 -o -name '*.h' -print0 | xargs -0 genstrings -o en.lproj

(基本都說genstrings -o en.lproj *.m就可以生成Localizable.strings,但是這個命令只能生成當(dāng)前目錄的计寇,并沒有遍歷子目錄,所以基本沒用)
這樣系統(tǒng)就會把子目錄用到NSLocalizedString函數(shù)的key值都寫到文件里脂倦。

需要注意的是番宁,NSLocalizedString(key,comment),用這個函數(shù)時赖阻,key不能是宏定義或者一些動態(tài)字符串蝶押,否則用上面的命令會報錯。

三火欧、系統(tǒng)如何選擇

  1. 在iOS7及之前版本棋电,系統(tǒng)只能設(shè)置一種語言,如果APP不支持系統(tǒng)設(shè)置的語言苇侵,選用備選語言的規(guī)則是:
    如果APP支持英文赶盔,直接選擇英文
    如果APP不支持英文,隨機(jī)挑選一個榆浓,不清楚這里挑選的規(guī)則于未。文檔上說會選用CFBundleDevelopmentRegion設(shè)置的語言,但我測試后發(fā)現(xiàn)并沒有陡鹃,系統(tǒng)直接忽略了這個字段烘浦。

舉個例子,APP支持中文跟英文杉适,當(dāng)系統(tǒng)語言是不是中文或英文時谎倔,都會選擇英文。若APP支持中文跟日文猿推,系統(tǒng)語言不是中文或日文片习,將會隨機(jī)挑選一個。

  1. 從iOS8開始蹬叭,系統(tǒng)語言可以設(shè)置一個語言列表藕咏,會根據(jù)這個語言列表的排序選用備選語言,規(guī)則就變了:

如果APP支持的語言在系統(tǒng)語言列表里有秽五,優(yōu)先選擇列表上排序靠前的語言孽查。
如果APP支持的語言沒在系統(tǒng)語言列表上,按CFBundleDevelopmentRegion的值選擇坦喘,無論APP是否支持英文盲再,英文不再是默認(rèn)的備選語言西设。

舉個例子,APP支持中文跟英文答朋,CFBundleDevelopmentRegion的值是中文贷揽,當(dāng)系統(tǒng)語言列表是[日文]或[日文,中文]時,會選擇中文梦碗,系統(tǒng)語言列表是[日文,英文]時禽绪,會選擇英文。

二洪规、 "AppleLanguages" 返回值 變化

ios8以后

NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
NSArray* languages = [def objectForKey:@"AppleLanguages"];

返回多了 區(qū)域信息印屁,類似于:

iOS 7: @"en",@"zh-Hans",@"zh-Hant"
iOS 8: @"en-US",@"zh-Hans-CN",@"zh-Hant-TW"

三、代碼實(shí)現(xiàn)

下面代碼 實(shí)現(xiàn) 了 應(yīng)用內(nèi) 設(shè)置語言斩例,繁體中文 雄人,簡體中文 都用簡體中文,其他用英文:
頭文件:

#import <Foundation/Foundation.h>

// 國際化
#define DDLocalizedString(key, comment) [[LocalizedUtil bundle] localizedStringForKey:(key) value:@"" table:nil]

typedef NS_ENUM(NSUInteger, DDLocalizedType) {
    DDLocalizedType_FollowSystem,
    DDLocalizedType_SimpleChinese,
    DDLocalizedType_English
};
@interface LocalizedUtil : NSObject

+ (NSBundle *)bundle;
+ (NSString *)userLanguage;
+ (void)setLocalizedType:(DDLocalizedType)type;
+ (DDLocalizedType)localizedType;

.m 文件:

#import "LocalizedUtil.h"

static NSString *LocalizedLanguage = nil;
static NSBundle *LocalizedBundle = nil;

@implementation LocalizedUtil

+ ( NSBundle * )bundle {
    
    if (!LocalizedBundle) {
        NSString *language = [self userLanguage];
        NSString *path = [[NSBundle mainBundle] pathForResource:language ofType:@"lproj" ];
        LocalizedBundle = [NSBundle bundleWithPath:path];
        
        if (!LocalizedBundle) { // 不存在樱拴,說明 設(shè)置了 不支持的語言柠衍,默認(rèn)改為英語洋满。
            LocalizedBundle = [self enBundle];
        }
    }
    return LocalizedBundle;
}
+ (NSBundle *)enBundle
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj" ];
    NSBundle *bundle = [NSBundle bundleWithPath:path];
    return bundle;
}

+(NSString *)userLanguage {
    
    if (LocalizedLanguage) {
        return LocalizedLanguage;
    }
    
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    
    NSString *language = [def valueForKey:@"userLanguage"];
    
    if (language.length > 0) {
        LocalizedLanguage = language;
    } else {
        NSArray* languages = [def objectForKey:@"AppleLanguages"];
        NSString *l =  [languages objectAtIndex:0];
        NSDictionary *components = [NSLocale componentsFromLocaleIdentifier:l];
        if (components[NSLocaleCountryCode]) {
            // 返回了 地區(qū)信息
            LocalizedLanguage = components[NSLocaleLanguageCode];
        } else {
            LocalizedLanguage = l;
        }
        if ([LocalizedLanguage hasPrefix:@"zh-Hant"]) { // 繁體 中文
            LocalizedLanguage = @"zh-Hans"; // 改為 簡體中文
        }
    }
    
    return LocalizedLanguage;
}

+(void)setUserlanguage:(NSString *)language
{
        
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    
    // 1.第一步改變bundle的值
    if (language.length == 0) {
        LocalizedBundle = [NSBundle mainBundle];
    } else {
        NSString *path = [[NSBundle mainBundle] pathForResource:language ofType:@"lproj" ];
        LocalizedBundle = [NSBundle bundleWithPath:path];
        
        if (!LocalizedBundle) { // 不存在晶乔,說明 設(shè)置了 不支持的語言,默認(rèn)改為英語牺勾。
            LocalizedBundle = [self enBundle];
        }
    }
    
    //2.持久化
    [def setValue:language forKey:@"userLanguage"];
    [def synchronize];
    
    LocalizedLanguage = language;
}

+ (void)setLocalizedType:(DDLocalizedType)type
{
    NSString *language = nil;
    switch (type) {
        case DDLocalizedType_FollowSystem:
            language = nil;
            break;
        case DDLocalizedType_SimpleChinese:
            language = @"zh-Hans";
            break;
        case DDLocalizedType_English:
            language = @"en";
            break;
        default:
            break;
    }
    
    [self setUserlanguage:language];
}

+ (DDLocalizedType)localizedType
{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    NSString *language = [def valueForKey:@"userLanguage"];
    if ([language isEqualToString:@"zh-Hans"]) {
        return DDLocalizedType_SimpleChinese;
    } else if ([language isEqualToString:@"en"]) {
        return DDLocalizedType_English;
    } else {
        return DDLocalizedType_FollowSystem;
    }
}

@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末正罢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子驻民,更是在濱河造成了極大的恐慌翻具,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件回还,死亡現(xiàn)場離奇詭異裆泳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)柠硕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門工禾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蝗柔,你說我怎么就攤上這事闻葵。” “怎么了癣丧?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵槽畔,是天一觀的道長。 經(jīng)常有香客問我胁编,道長厢钧,這世上最難降的妖魔是什么鳞尔? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮早直,結(jié)果婚禮上铅檩,老公的妹妹穿的比我還像新娘。我一直安慰自己莽鸿,他們只是感情好昧旨,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著祥得,像睡著了一般兔沃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上级及,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天乒疏,我揣著相機(jī)與錄音,去河邊找鬼饮焦。 笑死怕吴,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的县踢。 我是一名探鬼主播转绷,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼硼啤!你這毒婦竟也來了议经?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤谴返,失蹤者是張志新(化名)和其女友劉穎煞肾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嗓袱,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡籍救,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了渠抹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝙昙。...
    茶點(diǎn)故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖逼肯,靈堂內(nèi)的尸體忽然破棺而出耸黑,到底是詐尸還是另有隱情,我是刑警寧澤篮幢,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布大刊,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏缺菌。R本人自食惡果不足惜葫辐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望伴郁。 院中可真熱鬧耿战,春花似錦、人聲如沸焊傅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狐胎。三九已至鸭栖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間握巢,已是汗流浹背晕鹊。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留暴浦,地道東北人溅话。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像歌焦,于是被迫代替她去往敵國和親飞几。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Demo同步更新到Swift2.3本文地址: http://mokai.me/iOS-i18n.html 在真正...
    _GKK_閱讀 5,846評論 13 55
  • ** 原文發(fā)表在:https://www.xiaolei0808.com/2016/04/24/Localized...
    金小白先生閱讀 17,572評論 16 90
  • 目錄 概覽 各種資源的國際化 1.文本2.圖片3.nib4.其他資源 特定模塊/功能的國際化 1.APP圖標(biāo)2.應(yīng)...
    十拿九穩(wěn)啦閱讀 3,668評論 0 6
  • 最近公司的項目要求適配國際化同规,在過程中遇到挺多有意思的知識點(diǎn)循狰。 多語言大家都知道窟社,字母文字有顯著的形狀差別券勺。 但國...
    PengElement閱讀 6,625評論 0 6
  • 當(dāng)下的每一個選擇都是你的最佳選擇关炼。所以,做的每一件事無需后悔匣吊。 如我儒拂, 總是后悔前一天沒有多看書,沒有多寫文章色鸳。 ...
    梅子Mey閱讀 208評論 2 3