國際化

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ù)組存儲著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ù)存儲到對應(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容