iOS語(yǔ)言國(guó)際化/本地化-實(shí)踐總結(jié)

2018年09月07日

Build Apps for the World

1 添加要支持的國(guó)際語(yǔ)言

  1. 添加語(yǔ)言后面的括號(hào)內(nèi)容是該語(yǔ)言的國(guó)際標(biāo)準(zhǔn)縮寫(xiě)名


  2. 如選擇添加日語(yǔ)后,會(huì)彈出如下對(duì)話框,選擇Finish即可


  3. 如下選擇添加日語(yǔ),法語(yǔ),簡(jiǎn)體中文,繁體中文后,可以發(fā)現(xiàn)相應(yīng)的變化


2 本地化應(yīng)用名

本地化應(yīng)用名:App的名稱(chēng),根據(jù)設(shè)備語(yǔ)言的設(shè)置,顯示成對(duì)應(yīng)名稱(chēng)(如微信App,在簡(jiǎn)體中文語(yǔ)言下顯示成微信,在英文語(yǔ)言下顯示weChat)

2.1 選中info.plist文件,右鍵選擇新建文件

2.2 選擇創(chuàng)建文件類(lèi)型為Strings File

2.3 指定名稱(chēng)為InfoPlist.strings(名稱(chēng)必須是InfoPlist)

2.4 創(chuàng)建成功后

2.5 選中InfoPlist.strings,在Xcode的File inspection(Xcode右側(cè)文件檢查器)中點(diǎn)擊Localize,目的是選擇我們需要本地化的語(yǔ)言,如下圖:

注意:在點(diǎn)擊Localize之前,一定要保證第1步已經(jīng)添加了需要國(guó)際語(yǔ)言

2.6 彈出確認(rèn)對(duì)話框,默認(rèn)選擇English,你可展開(kāi)優(yōu)選選擇你需要本地化的語(yǔ)言,或者直接按默認(rèn),后續(xù)可以繼續(xù)添加你需要的國(guó)際語(yǔ)言

2.7 選擇本地化的語(yǔ)言后,可以看到InfoPlist.strings文件在文件檢查器欄的Locaization欄發(fā)生變化

2.8 將其他國(guó)際語(yǔ)言都勾上后,可以看到InfoPlist.strings文件也出現(xiàn)了多個(gè)子項(xiàng)的變化

2.9 從項(xiàng)目文件夾方向看看發(fā)生了什么

多語(yǔ)言本地化的核心思想
就是為每種語(yǔ)言單獨(dú)定義一份資源,iOS就是通過(guò)xxx.lproj目錄來(lái)定義每個(gè)語(yǔ)言的資源,這里的資源可以是圖片,文本,Storyboard,Xib等

每種語(yǔ)言都有自己的 語(yǔ)言代碼.lproj 文件夾,加載資源時(shí)只需要加載相應(yīng)語(yǔ)言文件夾下的資源,這步可以系統(tǒng)為我們完成,也可以手動(dòng)去做

2.10 先設(shè)置demo的display name為:本地化測(cè)試Demo

  • info.plist 文件中會(huì)出現(xiàn)display name的key value展示


  • 我們知道display name 的名字就是App安裝后再設(shè)備上顯示的名稱(chēng)


  • 通過(guò)顯示info.plist中的raw key value來(lái)獲取修改display name對(duì)應(yīng)的key:CFBundleDisplayName



看看官方解析咯
CFBundleDisplayName
CFBundleName
info.plist 的所有key查看 -Core Foundation Keys

CFBundleDisplayName

所以CFBundleDisplayName是可以用在infoPlist.strings上的。

2.11 分別在不同的語(yǔ)言所對(duì)應(yīng)InfoPlist.strings上設(shè)置本地化的App名稱(chēng)

// InfoPlist.strings(English) 文件
CFBundleDisplayName = "EnglishDemo";


// InfoPlist.strings(Chinese(Simplified)) 文件
CFBundleDisplayName = "簡(jiǎn)體Demo";


// InfoPlist.strings(Chinese(Tradictional)) 文件
CFBundleDisplayName = "繁體Demo";


// InfoPlist.strings(Japanese) 文件
CFBundleDisplayName = "日語(yǔ)Demo";


// InfoPlist.strings(French) 文件
CFBundleDisplayName = "法語(yǔ)Demo";

備注:CFBundleDisplayName可以使用雙引號(hào),也可以不使用雙引號(hào)!

2.12 獲取當(dāng)前模擬器當(dāng)前設(shè)置的語(yǔ)言

// ViewController.m
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
    NSLog(@"AppleLanguages 語(yǔ)言有 %@", languages);
    NSString *currentLanguage = languages.firstObject;
    NSLog(@"模擬器當(dāng)前語(yǔ)言:%@",currentLanguage);

}

2.13 設(shè)置模擬器的語(yǔ)言環(huán)境

在iOS設(shè)備上設(shè)置語(yǔ)言

2.14 運(yùn)行程序后各個(gè)語(yǔ)言本地化的效果展示

  1. 繁體環(huán)境下(模擬器當(dāng)前語(yǔ)言:zh-Hant-HK)
// 運(yùn)行結(jié)果
2018-09-04 16:49:40.056223+0800 LanguageLocalizationDemo[92506:3273624] AppleLanguages 語(yǔ)言有 (
    "zh-Hant-HK",
    "zh-Hans-US",
    en
)
2018-09-04 16:49:40.056505+0800 LanguageLocalizationDemo[92506:3273624] 模擬器當(dāng)前語(yǔ)言:zh-Hant-HK
  1. 英語(yǔ)環(huán)境下(模擬器當(dāng)前語(yǔ)言:en)
// 運(yùn)行結(jié)果
2018-09-04 17:00:37.811874+0800 LanguageLocalizationDemo[92874:3283615] AppleLanguages 語(yǔ)言有 (
    en
)
2018-09-04 17:00:37.812133+0800 LanguageLocalizationDemo[92874:3283615] 模擬器當(dāng)前語(yǔ)言:en
  1. 日語(yǔ)環(huán)境下(模擬器當(dāng)前語(yǔ)言:ja-US)
// 運(yùn)行結(jié)果
2018-09-05 10:33:16.423697+0800 LanguageLocalizationDemo[46412:14218145] AppleLanguages 語(yǔ)言有 (
    "ja-US",
    en
)
2018-09-05 10:33:16.423941+0800 LanguageLocalizationDemo[46412:14218145] 模擬器當(dāng)前語(yǔ)言:ja-US
  1. 簡(jiǎn)體中文環(huán)境下(模擬器當(dāng)前語(yǔ)言:zh-Hans-US)
// 運(yùn)行結(jié)果
2018-09-05 10:36:18.376366+0800 LanguageLocalizationDemo[46510:14225868] AppleLanguages 語(yǔ)言有 (
    "zh-Hans-US",
    "zh-Hant-US",
    "ja-US",
    en
)
2018-09-05 10:36:18.376628+0800 LanguageLocalizationDemo[46510:14225868] 模擬器當(dāng)前語(yǔ)言:zh-Hans-US
  1. 法語(yǔ)環(huán)境下(模擬器當(dāng)前語(yǔ)言:fr-US)
// 運(yùn)行結(jié)果
2018-09-05 10:47:12.397641+0800 LanguageLocalizationDemo[46634:14239902] AppleLanguages 語(yǔ)言有 (
    "fr-US",
    "zh-Hans-US",
    "zh-Hant-US",
    "ja-US",
    en
)
2018-09-05 10:47:12.398086+0800 LanguageLocalizationDemo[46634:14239902] 模擬器當(dāng)前語(yǔ)言:fr-US

當(dāng)然,模擬器設(shè)置對(duì)應(yīng)的語(yǔ)言之后,模擬器重啟完成時(shí)對(duì)應(yīng) App 的名稱(chēng)就會(huì)隨系統(tǒng)語(yǔ)言而變更,不需要重新 run 這個(gè)項(xiàng)目,而上述結(jié)果每次都進(jìn)行 run 操作的目的是觀察系統(tǒng)語(yǔ)言的變化及確定所設(shè)置的語(yǔ)言是否正確

2.15 影響通過(guò)AppleLanguageskey 從NSUserDefaults中獲取的支持語(yǔ)言的原因

  1. 根據(jù)設(shè)備曾經(jīng)添加過(guò)的語(yǔ)言返回結(jié)果
NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];

上面獲得的NSArray *languages內(nèi)容是根據(jù)當(dāng)前設(shè)備已經(jīng)添加過(guò)哪些語(yǔ)言決定的,模擬器默認(rèn)只有英文,所以你會(huì)看到2.14中打印的不同結(jié)果

  1. 受到 Xcode 的語(yǔ)言設(shè)定影響
    假設(shè)設(shè)備已經(jīng)添加了簡(jiǎn)體中文、繁體中文、英文、法語(yǔ)、日語(yǔ)。
    2.1 設(shè)備添加了對(duì)應(yīng)語(yǔ)言


2.2 Xcode 中的原因按默認(rèn)設(shè)置為跟隨系統(tǒng)


那么此時(shí)運(yùn)行下面代碼獲得的數(shù)組是:

NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
2018-09-05 10:47:12.397641+0800 LanguageLocalizationDemo[46634:14239902] AppleLanguages 語(yǔ)言有 (
    "fr-US",
    "zh-Hans-US",
    "zh-Hant-US",
    "ja-US",
    en
)
2018-09-05 10:47:12.398086+0800 LanguageLocalizationDemo[46634:14239902] 模擬器當(dāng)前語(yǔ)言:fr-US

打印結(jié)果是設(shè)備正常已添加的語(yǔ)言。

2.3 Xcode 中的語(yǔ)言設(shè)置為指定某一語(yǔ)言(此處設(shè)為English)時(shí),結(jié)果是:

2018-09-05 10:58:06.445970+0800 LanguageLocalizationDemo[46726:14250118] AppleLanguages 語(yǔ)言有 (
    en
)
2018-09-05 10:58:06.446199+0800 LanguageLocalizationDemo[46726:14250118] 模擬器當(dāng)前語(yǔ)言:en

AppleLanguages數(shù)組中只有一個(gè)en 元素
但模擬器真實(shí)語(yǔ)言環(huán)境沒(méi)有變化,還是法語(yǔ),且 App 名稱(chēng)同樣還是根據(jù)設(shè)備環(huán)境顯示成法語(yǔ)的名稱(chēng)

這里作出的對(duì)比,是希望以后再開(kāi)發(fā)調(diào)試時(shí)候,留意這些影響設(shè)備語(yǔ)言獲取的因子

同時(shí)需要注意的是,App 的名稱(chēng)不會(huì)隨 Xcode 的 application langue變化而變化,它僅僅跟隨設(shè)備實(shí)際設(shè)置的語(yǔ)言而變

3 本地化 代碼中的字符串

本地化 代碼中的字符串是指程序內(nèi)的字符串在不同的語(yǔ)言環(huán)境下顯示不同的內(nèi)容,比如首頁(yè)一詞,在簡(jiǎn)體中文下顯示就是首頁(yè),而在英文下則會(huì)顯示Home

本地化 代碼中的字符串流程與本地化 App 名稱(chēng)基本一致,同樣下面也會(huì)給出各個(gè)步驟的操作貼圖

3.1 選中要存放新建文件位置的文件夾后,通過(guò) command + n 快速創(chuàng)建文件

3.2 選擇創(chuàng)建文件類(lèi)型為Strings File

3.3 指定 Strings File 文件名稱(chēng)為 Localizable

使用這個(gè)名字原因它是系統(tǒng)默認(rèn)加載本地化文件名稱(chēng),后面會(huì)提到通過(guò)自定義其他名稱(chēng)來(lái)模塊化處理本地化及解耦


3.4 Localize Localizable.strings文件

3.5 勾選其他語(yǔ)言

到目前為止,上述步驟與本地化 App 名稱(chēng)是一樣的,不同點(diǎn)是 strings 文件的名稱(chēng)

3.6 在對(duì)應(yīng)語(yǔ)言文件中按 key-value 的形式寫(xiě)入需要本地化的字符串

// Localizable.strings(English) 文件
"home" = "home";

// Localizable.strings(Chinese(Simplified)) 文件
"home" = "簡(jiǎn)體主頁(yè)";

// Localizable.strings(Japanese) 文件
"home" = "日語(yǔ)主頁(yè)";

// Localizable.strings(Chinese(Traditional)) 文件
"home" = "繁體主頁(yè)";

// Localizable.strings(French) 文件
"home" = "法語(yǔ)主頁(yè)";

3.7 通過(guò)NSLocalizedString(key, comment)這個(gè)系統(tǒng)提供的宏,使用本地化文件中的內(nèi)容

  1. 環(huán)境語(yǔ)言的切換可以通過(guò)設(shè)備的語(yǔ)言設(shè)置Xcode中Scheme設(shè)置,這里推薦通過(guò) Xcode 進(jìn)行快速設(shè)置,這樣省去等待模擬器的重啟時(shí)間
  2. 下面是設(shè)置運(yùn)行效果
  • 簡(jiǎn)體中文


  • 英文


  • 法語(yǔ)


  • 繁體中文


  1. NSLocalizedString宏定義解析

localizedStringForKey:value:table: - NSBundle

3.8 NSLocalizedString 使用小技巧

  1. 使用NSLocalizedString按照給定的 key 查找對(duì)應(yīng) strings 文件時(shí),如果找不到該 key 對(duì)應(yīng)value 時(shí),默認(rèn)返回的值就是 key。
  • Localizable.strings(English)文件什么都沒(méi)寫(xiě)
  • NSLocalizedString使用的 key 為 lala
  • 當(dāng)查找不到時(shí),就會(huì)將 key 返回,如下圖:


  1. 假設(shè)你使用的是英文的名稱(chēng)作為 key,那么一般情況下,Localizable.strings(English)文件中的鍵值對(duì)應(yīng)該是這樣的"home" = "home";,即鍵值一樣,那就可以利用上面的第一點(diǎn),查找不到是返回 key 的特性,省去在Localizable.strings(English)文件中補(bǔ)上鍵值的情況(當(dāng)然,這是不建議的??)

4 模塊化管理本地化

4.1 模塊化管理的原因

  1. 從第3大點(diǎn)上可以知道,通過(guò)構(gòu)建一個(gè)系統(tǒng)默認(rèn)的名稱(chēng)的Localizable.strings文件,可以將項(xiàng)目中所有需要本地化語(yǔ)言的代碼字符串統(tǒng)一放在Localizable.strings文件中。
  2. 但是都放在一個(gè)地方雖然可以統(tǒng)一管理,但隨著項(xiàng)目的模塊的增多等情況,該文件內(nèi)容必定會(huì)存在內(nèi)容臃腫情況,雖然可通過(guò)注釋或者#pragma mark - <#desc#>來(lái)分層管理,但面向多人編程時(shí),同時(shí)修改一個(gè)文件導(dǎo)致的問(wèn)題更復(fù)雜

4.2 自定義.strings文件,實(shí)現(xiàn)模塊化管理

  1. 通過(guò)NSLocalizedStringFromTable宏,手動(dòng)指定查找 strings 文件。
NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)
  1. 自定義名稱(chēng)·strings文件(Module1.strings)

  2. 使用NSLocalizedStringFromTable


5 本地化圖片

5.1 方式1:類(lèi)似本地化代碼字符串方式,通過(guò)NSLocalizedString獲取語(yǔ)言的圖片名稱(chēng),從Assets.xcassets中獲取相應(yīng)圖片

  • 使用代碼示例


  • Assets.xcassets圖片命名

  • 對(duì)應(yīng) Localizable.strings 內(nèi)容

// Localizable.strings(English) 文件
"image-languge" = "english";

// Localizable.strings(Chinese(Simplified)) 文件
"image-languge" = "simplify";

// Localizable.strings(Japanese) 文件
"image-languge" = "japan";

// Localizable.strings(Chinese(Traditional)) 文件
"image-languge" = "french";

// Localizable.strings(French) 文件
"home" = "法語(yǔ)主頁(yè)";
  • 運(yùn)行效果


    法語(yǔ)

    英語(yǔ)

    其他請(qǐng)參考 demo

5.2 方式2:指定 bundle 的圖片,讓其具有本地化屬性(即把圖片資源放到對(duì)應(yīng)的語(yǔ)言lproj文件夾中)

  1. 拖拽一張圖片至項(xiàng)目 bundle 中


  2. 本地化圖片


  3. 將其他語(yǔ)言選上


  4. 在對(duì)應(yīng)圖片的本地化文件夾內(nèi)都可以看到有一張 icon 圖


  5. 將對(duì)應(yīng)語(yǔ)言的.lproj文件夾內(nèi)的 icon 圖替換成同名的其他 icon 圖



    其他語(yǔ)言一樣操作

  6. 完成第5步后回到項(xiàng)目,點(diǎn)擊對(duì)應(yīng)的語(yǔ)言.strings文件看到對(duì)應(yīng)的 icon


  7. 通過(guò) icon 名稱(chēng)langueIcon作為 key,使用NSLocalizedString獲取應(yīng)語(yǔ)言字符串

  • 運(yùn)行效果如5.1


本地化圖片需要多張圖片類(lèi)似的圖片,如果一次適配的語(yǔ)言較多情況下,那么包體積變大是不可避免的事情,這一點(diǎn)可考慮一下動(dòng)態(tài)獲取圖片的方法。這樣按需獲取在多語(yǔ)言情況下比較可行

6 本地化 Xib

6.1 本地化 Xib

  1. 創(chuàng)建 xib 的 vc


  2. Localize xib 文件,注意:直接選擇 Base,不要選其他

  • 選其他的話,會(huì)沒(méi)有生成對(duì)應(yīng)的 key-value


  1. 勾選其他的語(yǔ)言


相比于其他的.strings文件,xib 或 sb 本地化之后,對(duì)應(yīng)語(yǔ)言的.strings 文件是可以變換成特定 xib 樣式的


你可以選擇 讓其他語(yǔ)言以 strings 文件形式來(lái) 基于Base 的 xib;或者每個(gè)語(yǔ)言都成為獨(dú)立的 xib 文件
但是不建議使用獨(dú)立 xib 的形式,當(dāng)然如果不同語(yǔ)言不同布局的話,也是可以使這樣形式的

  1. 選擇 Base 的 String 自動(dòng)生成strings 文件內(nèi)容瀏覽
    系統(tǒng)會(huì)根據(jù)當(dāng)前 xib 中的子控件(限文本控件,如:Label、Button等),的 Object ID 生成內(nèi)容鍵值

  2. 根據(jù)語(yǔ)言修改對(duì)應(yīng) value 值即可,系統(tǒng)會(huì)自動(dòng)獲取xib 中控件 ID 然后匹配系統(tǒng)語(yǔ)言進(jìn)行內(nèi)容賦值


  3. 修改 Xcode 的語(yǔ)言設(shè)置,查看運(yùn)行結(jié)果

  • 英文


  • 法語(yǔ)


6.2 在Interface Builder中預(yù)覽本地化

在Interface Builder中,您可以在不運(yùn)行應(yīng)用程序的情況下預(yù)覽用戶界面的本地化。

  1. 在項(xiàng)目導(dǎo)航器中,選擇要預(yù)覽的文件.storyboard或.xib文件

  2. 選擇視圖>輔助編輯器>顯示助手編輯器

  3. 在助手編輯器跳轉(zhuǎn)欄中,打開(kāi)“助手”彈出菜單,滾動(dòng)并選擇“預(yù)覽”項(xiàng),然后從子菜單中選擇.storyboard或.xib文件(如果應(yīng)用程序用戶界面的預(yù)覽未顯示在助理編輯器中,請(qǐng)?jiān)趫D標(biāo)或大綱視圖中選擇要預(yù)覽的窗口或視圖)

  4. 在助理編輯器中,從右下角的語(yǔ)言彈出菜單中選擇要預(yù)覽的本地化。(本地化的預(yù)覽顯示在助理編輯器中。如果選擇實(shí)際語(yǔ)言,則不需要本地化或需要本地化但當(dāng)前不是本地化的字符串將以大寫(xiě)形式顯示)

6.3 添加新控件至 XIB

  1. 不會(huì)聯(lián)動(dòng)變化
    我們發(fā)現(xiàn),添加新控件后,相應(yīng)的 strings 文件沒(méi)有自動(dòng)發(fā)生變化??

注意:Xib相應(yīng)語(yǔ)言的strings一旦生成后,Base Xib有任何編輯都不會(huì)影響到strings,即刪除或添加了一個(gè)Label,strings也不會(huì)同步做相應(yīng)的改動(dòng)

  1. 手動(dòng)添加咯(當(dāng)然是可以的)
  • 獲取到對(duì)應(yīng) Label 的 ObjectID,然后參考之前生成 strings 之前已經(jīng)添加到 xib 的 label 處理格式,分別修改對(duì)應(yīng)語(yǔ)言的 strings 文件,如下:
  • 運(yùn)行效果

6.3 自動(dòng)化更新 strings 文件

  1. 方式1:使用ibtool生成新的.strings文件(后續(xù)會(huì)分析這個(gè)的使用步驟)
  • Xcode 為我們提供了 ibtool 工具來(lái)生成 Xib 的 strings 文件,命令如下
    ibtool XibController.xib --generate-strings-file ./XibController.strings
  • 但是這個(gè)ibtool翻譯的鍵值對(duì)中的值是按照xib上控件上填寫(xiě)的文本來(lái)顯示的,一般不是我們想要的,如果要實(shí)現(xiàn)更新,我們需要將XibController.strings和之前對(duì)應(yīng)語(yǔ)言文件夾fr.lproj等的XibController.strings比較,將XibController.string中多出來(lái)的key-value取出來(lái),追加到Main.string的尾部(實(shí)在麻煩)
  1. 方式2:使用腳本來(lái)實(shí)現(xiàn)自動(dòng)追加新 key-value,刪除不再存在的 key-value
    腳本內(nèi)還是通過(guò)使用 ibtool
  • 邏輯是:假設(shè)原來(lái)我們就有翻譯文件A,添加控件后,我們?cè)賵?zhí)行一次國(guó)際化指令,生成文件B,我們拿A和B對(duì)比,把B中多出來(lái)的鍵值對(duì)插入A文件的尾部,將A中有而B(niǎo)中沒(méi)有的鍵值對(duì)刪掉(即控件被刪除),這樣我們就算是更新了storyboard的翻譯文件了

  • 參照上述的邏輯,我們可以借助腳本文件來(lái)實(shí)現(xiàn),Xcode的Run Script也提供了腳本支持,可以讓我們?cè)贐uild后執(zhí)行腳本

2.1 新建 py 腳本


AutoGenStrings.py參考 demo 工程

2.2 選擇:Target -> Build Phases -> New Run Script Phase,在shell里面寫(xiě)入下面指令

#!/bin/bash
python ${SRCROOT}/${TARGET_NAME}/RunScript/AutoGenStrings.py ${SRCROOT}/${TARGET_NAME}

2.3 你也可以選擇Run script only when installing,這樣在編譯是不會(huì)云腳本,只有install的時(shí)候才會(huì)運(yùn)行腳本

2.4 新添加控件之后,編譯一下,對(duì)應(yīng)的 strings 文件會(huì)增加新控件的 key-value 對(duì),而刪除的控件的的 key-value 對(duì)會(huì)被注釋


之后有空會(huì)補(bǔ)上AutoGenStrings.py的解讀,參考的腳本原先只有 storyboard 的處理,這里擴(kuò)展至 xib

7 本地化Storyboard

  • 與 Xib 操作流程一致,請(qǐng)參考 Xib 的本地化流程

8 說(shuō)說(shuō)NSLocalizedString(key, comment)中 comment 參數(shù)的使用

第一個(gè)參數(shù)是:key的名字
第二個(gè)參數(shù)是:對(duì)這個(gè)“鍵值對(duì)”的注釋?zhuān)谟?code>genstrings工具生成Localizable.strings文件時(shí)會(huì)自動(dòng)加上去

一般情況下,語(yǔ)言翻譯的操作并不是我們程序員源來(lái)做的(當(dāng)然,nb的猿都會(huì)nb地接手這些工作),那么怎樣才能夠?qū)⒄Z(yǔ)言本地化strings文件分發(fā)出去同時(shí)又能夠很好的按流程工作呢?

8.1 直接在代碼中使用NSLocalizedString進(jìn)行臆想本地化實(shí)現(xiàn)

  • 此時(shí)的情況是本地沒(méi)有任何 strings 文件,利用NSLocalizedString的查找邏輯,key 不存在時(shí)直接返回 key 值
  • 所以開(kāi)發(fā)過(guò)程時(shí),界面顯示的就是 key 值,而推薦使用英文表示 key 的優(yōu)點(diǎn)就是:當(dāng)超出所支持語(yǔ)言時(shí),默認(rèn)使用英語(yǔ)。那使用英語(yǔ)翻譯的 key 正好滿足條件

8.2 通過(guò) genstrings 將使用了NSLocalizedStringviewController.m文件,生成對(duì)應(yīng)語(yǔ)言環(huán)境的 strings 文件

  • 當(dāng)所有的.m文件都使用NSLocalizedString修改好之后,就可以動(dòng)用genstrings工具了
  1. 啟動(dòng)終端,進(jìn)入工程所在目錄。
  2. 新建需要支持的語(yǔ)言.lproj 文件夾,位置默認(rèn)放在項(xiàng)目根目錄下
    目錄名會(huì)作用到Localizable.strings文件對(duì)應(yīng)的語(yǔ)言,所以目錄名稱(chēng)不能寫(xiě)錯(cuò)了。
mkdir zh-Hans.lproj
mkdir en.lproj
  • 推薦通過(guò) Xcode 幫我們生成,參考文章 “第1點(diǎn):添加要支持的國(guó)際語(yǔ)言”,這樣你還可以省去語(yǔ)言簡(jiǎn)寫(xiě)目錄名的煩惱,直接從 Xcode 中選擇你想要支持的國(guó)際語(yǔ)言

  • 選擇語(yǔ)言


  • 生成的.lproj文件夾

  • 發(fā)現(xiàn)沒(méi)有 en.lproj 文件夾,沒(méi)關(guān)系,點(diǎn)選 main.storyboard,在文件的 localize 位置勾上 English 選項(xiàng),同理 launch.storyboard 也同樣操作

  • 出現(xiàn)了 en.lproj

  1. 生成Localizable.strings文件
genstrings -o zh-Hans.lproj *.m
genstrings -o en.lproj *.m
genstrings -o ja.lproj *.m

-o <文件夾>,指定生成的Localizable.strings文件放置的目錄。
*.m,掃描所有的.m文件。這里支持的文件還包括.h, .java等。

  • 執(zhí)行完genstrings -o zh-Hans.lproj *.m命令之后,對(duì)應(yīng)的zh-Hans.lproj文件夾多了Localizable.strings,其他同理
  1. 生成Localizable.strings文件都拖拽到工程中,Xcode會(huì)自動(dòng)合并成一個(gè),并且對(duì)應(yīng)生成的內(nèi)容是按照前面NSLocalizedString(@"home", @"這個(gè)是用來(lái)在生成 strings 文件時(shí),在對(duì)應(yīng)的 key-value 行上的注釋?zhuān)脕?lái)提示翻譯員或者猿們的相關(guān)提示")生成的。

  2. 之后我們將這些文件分發(fā)到翻譯員(或者你自己手里)

注意:genstrings指令只能是該目錄下的文件遍歷,但不能實(shí)現(xiàn)遞歸遍歷,要實(shí)現(xiàn)遞歸變量,可以使用下述命令
find ./ -name *.m | xargs genstrings -o en.lproj
這是shell組合指令find+xargs,find ./ -name *.m 會(huì)遞歸所有.m文件并存在一個(gè)數(shù)組中,這個(gè)數(shù)組經(jīng)由pipe傳遞給了下一個(gè)指令,而xargs會(huì)將收到的數(shù)組一一分割,并交給genstrings執(zhí)行。

9 應(yīng)用內(nèi)設(shè)置語(yǔ)言(實(shí)踐后補(bǔ)上)

10 指定語(yǔ)言 bundle 獲取本地化字符串(實(shí)踐后補(bǔ)上)

  • 宏使用例子補(bǔ)充
#define NSLocalizedString(key, comment) \
        [NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:nil]
#define NSLocalizedStringFromTable(key, tbl, comment) \
        [NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:(tbl)]
#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) \
        [bundle localizedStringForKey:(key) value:@"" table:(tbl)]
#define NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment) \
        [bundle localizedStringForKey:(key) value:(val) table:(tbl)]

11 啟動(dòng)圖本地化(實(shí)踐后補(bǔ)上)

12 優(yōu)化(實(shí)踐后補(bǔ)上)

REF

Demo

LanguageLocalizationDemo - 第1-7點(diǎn)使用
LocalizationGenStringsDemo - 第8點(diǎn)使用


文/Jacob_LJ(簡(jiǎn)書(shū)作者)
PS:如非特別說(shuō)明,所有文章均為原創(chuàng)作品,著作權(quán)歸作者所有,轉(zhuǎn)載需聯(lián)系作者獲得授權(quán),并注明出處,所有打賞均歸本人所有!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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