國際化

demo

  1. storyboard中的文字
  2. 代碼中的文字
  3. app名稱的展示
  4. 資源文件的國際化
  5. 國際化腳本

國際化原理

核心思想就是為每種語言單獨(dú)定義一份資源。
iOS就是通過xxx.lproj目錄來定義每個(gè)語言的資源酸茴,這里的資源可以是圖片分预,文本,Storyboard薪捍,Xib等笼痹。
每種語言都有自己的 語言代碼.lproj文件夾配喳,加載資源時(shí)只需要加載相應(yīng)語言文件夾下的資源就OK
例如:根目錄下英語的為en.lproj,中文的為zh-Hans.lproj凳干。

國際化過程

  1. 首先添加國際化配置
    • 選中project->Info->Localizations晴裹,然后點(diǎn)擊"+",添加需要國際化/本地化的語言救赐,如下圖(默認(rèn)需要勾選Use Base Internationalization)
      圖片引用于:VV木公子
      image
    • 點(diǎn)擊+后涧团,選擇后綴為Chinese (Simplified)(zh-Hans)簡體中文,后綴為(zh-Hant)為繁體中文经磅。
    • 在這說一句后綴問題泌绣,所有iOS支持的語言及后綴,都可以在點(diǎn)擊+后出現(xiàn)的語言中找到预厌,其中最下面的other下是全部的集合阿迈。其中英語的后綴為(en)
  2. 應(yīng)用名稱
    • 選中Info.plist(或者其他你想創(chuàng)建的位置,現(xiàn)在創(chuàng)建在info.plist所在的文件)轧叽,按下鍵盤上的command + N苗沧,選擇Strings File(iOS->Resource->Strings File)

    • 文件名字命名為InfoPlist,且必須是這個(gè)名字

    • 選中InfoPlist.strings炭晒,在Xcode右側(cè)選中文件標(biāo)志->選中Localize待逞,目的是選擇我們需要本地化的語言 如下圖:

      image

    • 點(diǎn)擊Localize后,在彈出框中->點(diǎn)擊base->展開的列表中選擇English->隨后選中右下角的Localize

    • 此時(shí)右側(cè)會(huì)變成下圖模樣腰埂,勾選Chinese

      image

    • 此時(shí)InfoPlist.strings變成了文件夾飒焦,文件中有兩個(gè)文件。程序啟動(dòng)時(shí)屿笼,會(huì)根據(jù)操作系統(tǒng)設(shè)置的語言牺荠,自動(dòng)加載InfoPlist.strings文件下對應(yīng)的語言文件,然后顯示應(yīng)用程序的名字驴一。

      • 在InfoPlist.strings(english)文件中加入如下代碼:
      // Localizable App Name是App在英語環(huán)境環(huán)境下顯示的名稱
      CFBundleDisplayName = "Localizable App Name";
      或者
      "CFBundleDisplayName" = "Localizable App Name";
      
      • 在InfoPlist.strings(Chinese(Simplified))中加入如下代碼
      CFBundleDisplayName = "國際化App名稱";
      
    • app展示名字本地化結(jié)束
      補(bǔ)充

      InfoPlist.strings文件是對Info.plist這個(gè)配置文件進(jìn)行的國際化休雌,這個(gè)文件的國際化,不單單是app名稱的設(shè)置肝断,還包括權(quán)限的申請等的配置杈曲。關(guān)鍵在于這個(gè)文件的配置KEY是固定值,例如: app名字的key CFBundleDisplayName, 相機(jī)權(quán)限的申請key NSCameraUsageDescription等

      • 首先你將需要配置的屬性添加到Info.plist文件中
      • 其次查看這個(gè)屬性的key, 點(diǎn)擊這個(gè)文件的任意一項(xiàng)胸懈,兩個(gè)指頭同時(shí)點(diǎn)擊担扑,選擇彈出框的Show Raw Keys/Values,文件的展示就變成了key-value格式趣钱,此時(shí)你就可以找到你想要國際化屬性的key
      • 最后在InfoPlist.strings文件中涌献,做對應(yīng)的配置即可
      • 詳細(xì)操作參考 iOS10權(quán)限聲明國際化
  3. 代碼中字符串的本地化
    • 與上類似,創(chuàng)建一個(gè)Localizable.strings的文件首有,創(chuàng)建步驟與上面一致燕垃。
    • 然后我們只需要在Localizable.strings下對應(yīng)的文件中枢劝,分別以Key-Value的形式,為代碼中每一個(gè)需要本地化的字符串賦值
    // Localizable.strings (Simplified)文件中
    localization = "本地化";
    internationalizartion = "國際化";
    //Localizable.strings (English)文件中
    localization = "localization";
    internationalizartion = "internationalizartion";
    
    在要使用這些字段的.m文件中
    // NSLocalizedString(key, comment) 本質(zhì)
    // NSlocalizeString 第一個(gè)參數(shù)是內(nèi)容,根據(jù)第一個(gè)參數(shù)去對應(yīng)語言的文件中取對應(yīng)的字符串卜壕,第二個(gè)參數(shù)將會(huì)轉(zhuǎn)化為字符串文件里的注釋您旁,可以傳nil,也可以傳空字符串@""轴捎。
    //#define NSLocalizedString(key, comment) [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
    NSString *localization = NSLocalizedString(@"localization", nil);
    NSString *internationalizartion = NSLocalizedString(@"internationalizartion", nil);
    self.array = @[localization, internationalizartion];
    取得并使用
    
    • 代碼中字符串的本地化結(jié)束
    • 我們不需要在Localizable.strings(English)文件添加Key-Value鹤盒。原因如下:系統(tǒng)根據(jù)某個(gè)key去獲取對應(yīng)的字符串時(shí),如果沒有找到轮蜕,那么就會(huì)以key作為value返回。
    • 模擬不同的語言環(huán)境,不需要在模擬器中的設(shè)置中去做细燎。在Xcode中,command+shift+<出現(xiàn)的界面中做如下設(shè)置:
      Run -> Arguments -> Arguments Passed On launch 中添加-AppleLanguages (en)和-AppleLanguages (zh-Hans)然后選中其中一個(gè),運(yùn)行的app中的語言設(shè)置就是相應(yīng)語言的
      image
  4. 多人開發(fā)情況下的字符串本地化
    • 上面介紹的代碼中字符串的本地化是使用的是默認(rèn)的文件名"Localizable",因?yàn)閱?dòng)程序時(shí)瘟忱,系統(tǒng)將根據(jù)語言加載相應(yīng)的文件得到其對應(yīng)的字符串文件触菜,這個(gè)字符串可以通過系統(tǒng)將NSLocalizedString中的宏生成名為“Localizable.strings”的文件。那么如何讓系統(tǒng)加載我們自己命名的本地化文件而非系統(tǒng)默認(rèn)的Localizable.strings呢生逸?這就是 NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)的用處遍尺。
      也就是說,如果你的strings文件名字不是Localizable而是自定義的話呐能,如VVS.strings懊蒸,那么你就得使用NSLocalizedStringFromTable這個(gè)宏來讀取本地化字符串舌仍。
    // key:系統(tǒng)根據(jù)key取字符串
    // tbl:自定義strings文件的名字
    // comment:可以不傳
    NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)
    
    .m文件中
    NSString *title = NSLocalizedStringFromTable(@"click", @"VVS", nil);
    [self.btn setTitle:title forState:UIControlStateNormal];
    
  5. 圖片本地化
    • Assets.xcassets 不支持本地化,所以需要本地化的通危,可以單獨(dú)放到一個(gè)新的文件目錄下
    • 拖拽一張需要本地化的圖片到Xcode中/或者自定義的文件下統(tǒng)一處理這些需要本地化的圖片
    • 在Localizable.strings文件下相應(yīng)文件中設(shè)置key-value铸豁,通過NSLocalizedString(key,comment)來獲取相應(yīng)的字符串,然后根據(jù)這個(gè)字符串再獲取圖片菊碟。
    NSString *imageName = NSLocalizedString(@"icon", nil);
    UIImage *image = [UIImage imageNamed:imageName];
    self.imageView.image = image;
    **缺點(diǎn)**
    1. 工作量很大
    2. storyboard/xib中不能直接使用节芥,需要代碼中判斷重新取正確的圖像名,并重新賦值
    
    • 或者**把這張圖片當(dāng)做InfoPlist.strings去處理, 即選中圖片 - 點(diǎn)擊Localize 這些操作 ** 。然后這個(gè)圖片會(huì)變成文件夾模式头镊,點(diǎn)擊任意一個(gè)文件蚣驼,找到文件所在位置,然后替換成你想要顯示的文件即可(文件名保持一致)相艇。
    **優(yōu)點(diǎn)**
    就當(dāng)做正常的圖片使用即可颖杏。系統(tǒng)會(huì)根據(jù)語言設(shè)置找到對應(yīng)的圖片
    
  6. 查看/切換本地語言
    • 應(yīng)用啟動(dòng)時(shí),首先會(huì)讀取NSUserDefaults中的key為AppleLanguages對應(yīng)的value坛芽,該value是一個(gè)String數(shù)組留储,也就是說,我們訪問這個(gè)名為AppleLanguages的key可以返回一個(gè)string數(shù)組咙轩,該數(shù)組存儲(chǔ)著APP支持的語言列表获讳,數(shù)組的第一項(xiàng)為APP當(dāng)前默認(rèn)的語言。
    NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
    NSString *currentLanguage = languages.firstObject;
    NSLog(@"模擬器當(dāng)前語言:%@",currentLanguage);
    
    • 同理活喊,既然我們可以通過AppleLanguages這個(gè)key從NSUserDefaults中取出語言數(shù)組丐膝,那么我們也可以給AppleLanguages這個(gè)key賦值來達(dá)到切換本地語言的效果,從此以后钾菊,我們就無需頻繁的去模擬器的設(shè)置->通用->語言與地區(qū) 中切換語言
    // 切換語言前
    NSArray *langArr1 = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
    NSString *language1 = langArr1.firstObject;
    NSLog(@"模擬器語言切換之前:%@",language1);
    
    // 切換語言
    NSArray *lans = @[@"en"];
    [[NSUserDefaults standardUserDefaults] setObject:lans forKey:@"AppleLanguages"];
    
    // 切換語言后
    NSArray *langArr2 = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
    NSString *language2 = langArr2.firstObject;
    NSLog(@"模擬器語言切換之后:%@",language2);
    
    • 與第三條中的最后一條相對比尤误,其實(shí)本質(zhì)上就是給NSUserDefaults中名為AppleLanguages的key賦值
    • 還有一種方式如下圖
      images
    • app內(nèi)的語言切換。一個(gè)App切換語言的Demo
  7. storyboard/Xib 的本地化
    • 在這個(gè)Xib/storyboard文件结缚,完成的差不多的時(shí)候损晤,對他進(jìn)行本地化,無外乎红竭,點(diǎn)中文件尤勋,Xcode右側(cè)本地化操作,操作步驟與上面類似
    • 本地化后茵宪,在有所改變最冰,已經(jīng)本地化的文件不會(huì)變化,所以需要隨時(shí)更新稀火。一個(gè)笨的方法就是暖哨,去掉勾選的English和Chinese,然后會(huì)提示remove->選中delete選項(xiàng),然后在勾選English和Chinese凰狞,然后會(huì)重新生成
    • 友情提示篇裁,在Xib/storyboard中生成的文件中,主要使用ObjectID赡若,先刪除然后重新生成达布,同一個(gè)控件的ObjectID不會(huì)發(fā)生變化。這樣就可以記錄之前的逾冬,然后對最新的略微改變即可黍聂。
    /* Class = "UILabel"; text = "國際化測試"; ObjectID = "knJ-x1-3Rk"; */
    "knJ-x1-3Rk.text" = "國際化測試";
    
  8. 腳本
  9. 第8項(xiàng)的腳本適應(yīng)用Excel表格數(shù)據(jù)與配置文件的轉(zhuǎn)化匹厘。本項(xiàng)的適用于,項(xiàng)目工程開始很久后脐区,突然想要國際化配置集乔,整個(gè)工程很多地方都需要處理。
    • 第一項(xiàng)代碼中的待處理項(xiàng)

      • 如果你最開始就在代碼中已經(jīng)預(yù)先設(shè)置了NSLocalizedString(@"使用幫助", nil)類似的字段坡椒,只差生成對應(yīng)的key-value時(shí),你可以
        首先切換到需要處理的目錄下
        cd ****
        其次創(chuàng)建對應(yīng)的文件
        mkdir zh-Hans.lproj
        mkdir en.lproj
        最后查找目錄下后綴為.m的文件尤溜,然后生成對應(yīng)的數(shù)據(jù)存儲(chǔ)到對應(yīng)文件夾下
        find ./ -name *.m | xargs genstrings -o en.lproj
        find ./ -name *.m | xargs genstrings -o zh-Hans.lproj
        
    • 如果你什么也沒配置倔叼,就是簡單的將相關(guān)展示文字設(shè)置為對應(yīng)的中文字符

      • 首先你需要全局替換需要配置的中文字符,并以已經(jīng)設(shè)置的中文字符為key
        首先以正則表達(dá)式: (@"[^"]*[\u4E00-\u9FA5]+[^"\n]*?")\s* 來全局查找類似于 @"我的" 這個(gè)格式的字符
        然后在工程中 點(diǎn)擊搜索框 -> 替換Find 為 replace, 然后點(diǎn)擊緊挨著的text 替換為Regular Expression
        上面輸入:(@"[^"]*[\u4E00-\u9FA5]+[^"\n]*?")\s*
        下面輸入:NSLocalizedString\($1\, nil)
        中間的in ** 你可以點(diǎn)擊一下后宫莱,選擇你需要處理的文件夾
        最后開始替換
        
      • 隨后你就可以參考上一個(gè)選項(xiàng)進(jìn)行處理丈攒, 或者你可以使用 iOS 多語言版本的開發(fā)(三)這個(gè)教程中的工具進(jìn)行處理
      • 簡單的使用以上基本包括,更復(fù)雜的使用授霸,例如:動(dòng)態(tài)字體巡验,日期展示,數(shù)字展示等相關(guān)的碘耳,請查看字符串本地化這篇介紹显设。
    • 第二項(xiàng)是xib或者storyboard中的待處理項(xiàng)

      • 首先就是基礎(chǔ)操作,對每個(gè)需要進(jìn)行配置的xib文件辛辨,仿照第7項(xiàng)操作捕捂。即手動(dòng)開啟每個(gè)的本地化。
      • 然后就是對這些xib的自動(dòng)化更新配置了斗搞。即每次如果xib有改動(dòng)指攒,需要更新本地化數(shù)據(jù)時(shí)。讓其自動(dòng)化處理僻焚。腳本代碼文件允悦。原始操作流程參考iOS國際化詳解
      • 簡單步驟描述
        • 將存放腳本文件的文件夾,導(dǎo)入腳本文件到項(xiàng)目的根目錄

          腳本文件夾 RunScript/AutoGenStrings.py
          導(dǎo)入到     Desktop/cf-ios/CF/RunScript/AutoGenStrings.py
          Desktop桌面虑啤, cf-ios 工程所在的文件夾名字隙弛, CF為工程名字
          
        • 選擇項(xiàng)目 -> targes -> Build Phases -> + -> New Run Script Phase,將下面代碼copy到對應(yīng)的路徑

          #!/bin/sh
          python ${SRCROOT}/${TARGET_NAME}/RunScript/AutoGenStrings.py ${SRCROOT}/${TARGET_NAME}
          
          詳細(xì)步驟參考
        • Build Setting -> Deployment -> Deployment Location / Deployment Postprocessing -> Yes

          詳細(xì)步驟參考

        • 注意文件路徑中不能擁有空格狞山,否則Xcode腳本會(huì)找不到文件的錯(cuò)誤

        • 注意開啟了Deployment Location / Deployment Postprocessing 后驶鹉,會(huì)導(dǎo)致工程無法調(diào)試(debug),關(guān)閉后即可

        • 注意運(yùn)行后可能出現(xiàn)This app could not be installed at this time.提示,關(guān)閉Deployment Location / Deployment Postprocessing設(shè)置铣墨,然后clean工程室埋,重新運(yùn)行即可。如果這個(gè)方式無法解決,可以嘗試重啟Xcode, 清楚模擬器的緩存或者重啟模擬器姚淆。

        • 重點(diǎn)需要時(shí)在開啟孕蝉,不需要時(shí)請關(guān)閉,防止意外情況腌逢。

參考資料
簡書:VV木公子
簡書:iOS 國際化的設(shè)置大全
簡書:iOS App的國際化降淮,以及App內(nèi)的語言切換
簡書:iOS國際化
iOS國際化——通過腳本使storyboard翻譯自增

簡書:iOS國際化詳解
簡書:本地化 genstrings
很全的介紹:字符串本地化
iOS 多語言版本的開發(fā)(一)
iOS 多語言版本的開發(fā)(二)
iOS 多語言版本的開發(fā)(三)
iOS10權(quán)限聲明國際化
Info.plist的秘密(raywenderlich筆記)
plist字段列表,很全

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末搏讶,一起剝皮案震驚了整個(gè)濱河市佳鳖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌媒惕,老刑警劉巖系吩,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異妒蔚,居然都是意外死亡穿挨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門肴盏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來科盛,“玉大人,你說我怎么就攤上這事菜皂≌昝啵” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵恍飘,是天一觀的道長但壮。 經(jīng)常有香客問我,道長常侣,這世上最難降的妖魔是什么蜡饵? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮胳施,結(jié)果婚禮上溯祸,老公的妹妹穿的比我還像新娘。我一直安慰自己舞肆,他們只是感情好焦辅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著椿胯,像睡著了一般筷登。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哩盲,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天前方,我揣著相機(jī)與錄音狈醉,去河邊找鬼。 笑死惠险,一個(gè)胖子當(dāng)著我的面吹牛苗傅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播班巩,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼渣慕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了抱慌?” 一聲冷哼從身側(cè)響起逊桦,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎抑进,沒想到半個(gè)月后强经,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡单匣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宝穗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片户秤。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖逮矛,靈堂內(nèi)的尸體忽然破棺而出鸡号,到底是詐尸還是另有隱情,我是刑警寧澤须鼎,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布鲸伴,位于F島的核電站,受9級特大地震影響晋控,放射性物質(zhì)發(fā)生泄漏汞窗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一赡译、第九天 我趴在偏房一處隱蔽的房頂上張望仲吏。 院中可真熱鬧,春花似錦蝌焚、人聲如沸裹唆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽许帐。三九已至,卻和暖如春毕谴,著一層夾襖步出監(jiān)牢的瞬間成畦,已是汗流浹背距芬。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留羡鸥,地道東北人蔑穴。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像惧浴,于是被迫代替她去往敵國和親存和。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

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