添加語言後面的括號內容是該語言的國際標準縮寫名 html
如選擇添加日語後,會彈出以下對話框,選擇Finish便可 java
以下選擇添加日語,法語,簡體中文,繁體中文後,能夠發現相應的變化 python
本地化應用名:App的名稱,根據設備語言的設置,顯示成對應名稱(~如微信App,在簡體中文語言下顯示成微信,在英文語言下顯示weChat~)git
注意:在點擊Localize以前,必定要保證第1步已經添加了須要國際語言程序員
多語言本地化的核心思想 就是爲每種語言單獨定義一份資源,iOS就是經過xxx.lproj目錄來定義每一個語言的資源,這裏的資源能夠是圖片,文本,Storyboard,Xib等github
每種語言都有本身的
語言代碼.lproj
文件夾,加載資源時只須要加載相應語言文件夾下的資源,這步能夠系統爲咱們完成,也能夠手動去作shell
info.plist 文件中會出現display name的key value展現 編程
咱們知道display name 的名字就是App安裝後再設備上顯示的名稱 swift
經過顯示info.plist中的raw key value來獲取修改display name對應的key:CFBundleDisplayName c#
看看官方解析咯 CFBundleDisplayName CFBundleName info.plist 的全部key查看 -Core Foundation Keys
因此CFBundleDisplayName是能夠用在infoPlist.strings上的。
// InfoPlist.strings(English) 文件
CFBundleDisplayName = "EnglishDemo";
// InfoPlist.strings(Chinese(Simplified)) 文件
CFBundleDisplayName = "簡體Demo";
// InfoPlist.strings(Chinese(Tradictional)) 文件
CFBundleDisplayName = "繁體Demo";
// InfoPlist.strings(Japanese) 文件
CFBundleDisplayName = "日語Demo";
// InfoPlist.strings(French) 文件
CFBundleDisplayName = "法語Demo";
複製代碼
備註:CFBundleDisplayName可使用雙引號,也能夠不使用雙引號!
// ViewController.m
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
NSLog(@"AppleLanguages 語言有 %@", languages);
NSString *currentLanguage = languages.firstObject;
NSLog(@"模擬器當前語言:%@",currentLanguage);
}
複製代碼
// 運行結果
2018-09-04 16:49:40.056223+0800 LanguageLocalizationDemo[92506:3273624] AppleLanguages 語言有 (
"zh-Hant-HK",
"zh-Hans-US",
en
)
2018-09-04 16:49:40.056505+0800 LanguageLocalizationDemo[92506:3273624] 模擬器當前語言:zh-Hant-HK
複製代碼
// 運行結果
2018-09-04 17:00:37.811874+0800 LanguageLocalizationDemo[92874:3283615] AppleLanguages 語言有 (
en
)
2018-09-04 17:00:37.812133+0800 LanguageLocalizationDemo[92874:3283615] 模擬器當前語言:en
複製代碼
// 運行結果
2018-09-05 10:33:16.423697+0800 LanguageLocalizationDemo[46412:14218145] AppleLanguages 語言有 (
"ja-US",
en
)
2018-09-05 10:33:16.423941+0800 LanguageLocalizationDemo[46412:14218145] 模擬器當前語言:ja-US
複製代碼
// 運行結果
2018-09-05 10:36:18.376366+0800 LanguageLocalizationDemo[46510:14225868] AppleLanguages 語言有 (
"zh-Hans-US",
"zh-Hant-US",
"ja-US",
en
)
2018-09-05 10:36:18.376628+0800 LanguageLocalizationDemo[46510:14225868] 模擬器當前語言:zh-Hans-US
複製代碼
// 運行結果
2018-09-05 10:47:12.397641+0800 LanguageLocalizationDemo[46634:14239902] AppleLanguages 語言有 (
"fr-US",
"zh-Hans-US",
"zh-Hant-US",
"ja-US",
en
)
2018-09-05 10:47:12.398086+0800 LanguageLocalizationDemo[46634:14239902] 模擬器當前語言:fr-US
複製代碼
固然,模擬器設置對應的語言以後,模擬器重啓完成時對應 App 的名稱就會隨系統語言而變動,不須要從新 run 這個項目,而上述結果每次都進行 run 操做的目的是觀察系統語言的變化及肯定所設置的語言是否正確
AppleLanguages
key 從NSUserDefaults
中獲取的支持語言的緣由NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
複製代碼
上面得到的NSArray *languages
內容是根據當前設備已經添加過哪些語言決定的,模擬器默認只有英文,因此你會看到2.14中打印的不一樣結果
2.2 Xcode 中的緣由按默認設置爲跟隨系統
那麼此時運行下面代碼得到的數組是:
NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
複製代碼
2018-09-05 10:47:12.397641+0800 LanguageLocalizationDemo[46634:14239902] AppleLanguages 語言有 (
"fr-US",
"zh-Hans-US",
"zh-Hant-US",
"ja-US",
en
)
2018-09-05 10:47:12.398086+0800 LanguageLocalizationDemo[46634:14239902] 模擬器當前語言:fr-US
複製代碼
打印結果是設備正常已添加的語言。
2.3 Xcode 中的語言設置爲指定某一語言(~此處設爲English~)時,結果是:
2018-09-05 10:58:06.445970+0800 LanguageLocalizationDemo[46726:14250118] AppleLanguages 語言有 (
en
)
2018-09-05 10:58:06.446199+0800 LanguageLocalizationDemo[46726:14250118] 模擬器當前語言:en
複製代碼
AppleLanguages數組中只有一個en 元素 但模擬器真實語言環境沒有變化,仍是法語,且 App 名稱一樣仍是根據設備環境顯示成法語的名稱
這裏做出的對比,是但願之後再開發調試時候,留意這些影響設備語言獲取的因子
同時須要注意的是,App 的名稱不會隨 Xcode 的 application langue變化而變化,它僅僅跟隨設備實際設置的語言而變
本地化 代碼中的字符串
是指程序內的字符串在不一樣的語言環境下顯示不一樣的內容,好比首頁
一詞,在簡體中文下顯示就是首頁
,而在英文下則會顯示Home
。
本地化 代碼中的字符串
流程與本地化 App 名稱
基本一致,一樣下面也會給出各個步驟的操做貼圖
command + n
快速建立文件Localizable
使用這個名字緣由它是系統默認加載本地化文件名稱,後面會提到經過自定義其餘名稱來模塊化處理本地化及解耦
到目前爲止,上述步驟與本地化 App 名稱是同樣的,不一樣點是 strings 文件的名稱
// Localizable.strings(English) 文件
"home" = "home";
// Localizable.strings(Chinese(Simplified)) 文件
"home" = "簡體主頁";
// Localizable.strings(Japanese) 文件
"home" = "日語主頁";
// Localizable.strings(Chinese(Traditional)) 文件
"home" = "繁體主頁";
// Localizable.strings(French) 文件
"home" = "法語主頁";
複製代碼
NSLocalizedString(key, comment)
這個系統提供的宏,使用本地化文件中的內容設備的語言設置
或 Xcode中Scheme設置
,這裏推薦經過 Xcode 進行快速設置,這樣省去等待模擬器的重啓時間lala
"home" = "home";
,即鍵值同樣,那就能夠利用上面的第一點,查找不到是返回 key 的特性,省去在Localizable.strings(English)文件中補上鍵值的狀況(~固然,這是不建議的😆~)註釋
或者#pragma mark - <#desc#>
來分層管理,但面向多人編程時,同時修改一個文件致使的問題更復雜.strings
文件,實現模塊化管理NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)
複製代碼
自定義名稱·strings
文件(Module1.strings
)
使用NSLocalizedStringFromTable
NSLocalizedString
獲取語言的圖片名稱,從Assets.xcassets
中獲取相應圖片使用代碼示例
Assets.xcassets
圖片命名
對應 Localizable.strings 內容
// 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" = "法語主頁";
複製代碼
拖拽一張圖片至項目 bundle 中
本地化圖片
將其餘語言選上
在對應圖片的本地化文件夾內均可以看到有一張 icon 圖
將對應語言的.lproj
文件夾內的 icon 圖替換成同名的其餘 icon 圖
完成第5步後回到項目,點擊對應的語言.strings文件看到對應的 icon
經過 icon 名稱langueIcon
做爲 key,使用NSLocalizedString
獲取應語言字符串
本地化圖片須要多張圖片相似的圖片,若是一次適配的語言較多狀況下,那麼包體積變大是不可避免的事情,這一點可考慮一下動態獲取圖片的方法。這樣按需獲取在多語言狀況下比較可行
建立 xib 的 vc
Localize xib 文件,注意:直接選擇 Base,不要選其餘
相比於其餘的
你能夠選擇 讓其餘語言以 strings 文件形式來 基於Base 的 xib;或者每一個語言都成爲獨立的 xib 文件 可是不建議使用獨立 xib 的形式,固然若是不一樣語言不一樣佈局的話,也是可使這樣形式的.strings
文件,xib 或 sb 本地化以後,對應語言的.strings 文件是能夠變換成特定 xib 樣式的
選擇 Base 的 String 自動生成strings 文件內容瀏覽 系統會根據當前 xib 中的子控件(~限文本控件,如:Label、Button等~),的 Object ID 生成內容鍵值
根據語言修改對應 value 值便可,系統會自動獲取xib 中控件 ID 而後匹配系統語言進行內容賦值
修改 Xcode 的語言設置,查看運行結果
英文
法語
在Interface Builder中,您能夠在不運行應用程序的狀況下預覽用戶界面的本地化。
在項目導航器中,選擇要預覽的文件.storyboard或.xib文件
選擇視圖>輔助編輯器>顯示助手編輯器
在助手編輯器跳轉欄中,打開「助手」彈出菜單,滾動並選擇「預覽」項,而後從子菜單中選擇.storyboard或.xib文件(~若是應用程序用戶界面的預覽未顯示在助理編輯器中,請在圖標或大綱視圖中選擇要預覽的窗口或視圖~)
在助理編輯器中,從右下角的語言彈出菜單中選擇要預覽的本地化。(~本地化的預覽顯示在助理編輯器中。若是選擇實際語言,則不須要本地化或須要本地化但當前不是本地化的字符串將以大寫形式顯示~)
注意:Xib相應語言的strings一旦生成後,Base Xib有任何編輯都不會影響到strings,即刪除或添加了一個Label,strings也不會同步作相應的改動
ibtool
生成新的.strings
文件(~後續會分析這個的使用步驟~)ibtool
工具來生成 Xib 的 strings 文件,命令以下 ibtool XibController.xib --generate-strings-file ./XibController.strings
ibtool
翻譯的鍵值對中的值是按照xib上控件上填寫的文原本顯示的,通常不是咱們想要的,若是要實現更新,咱們須要將XibController.strings和以前對應語言文件夾fr.lproj
等的XibController.strings比較,將XibController.string中多出來的key-value取出來,追加到Main.string的尾部(~實在麻煩~)ibtool
邏輯是:假設原來咱們就有翻譯文件A,添加控件後,咱們再執行一次國際化指令,生成文件B,咱們拿A和B對比,把B中多出來的鍵值對插入A文件的尾部,將A中有而B中沒有的鍵值對刪掉(即控件被刪除),這樣咱們就算是更新了storyboard的翻譯文件了
參照上述的邏輯,咱們能夠藉助腳本文件來實現,Xcode的Run Script也提供了腳本支持,可讓咱們在Build後執行腳本
2.1 新建 py 腳本
2.2 選擇:Target -> Build Phases -> New Run Script Phase,在shell裏面寫入下面指令
#!/bin/bash
python ${SRCROOT}/${TARGET_NAME}/RunScript/AutoGenStrings.py ${SRCROOT}/${TARGET_NAME}
複製代碼
2.3 你也能夠選擇Run script only when installing
,這樣在編譯是不會雲腳本,只有install的時候纔會運行腳本
2.4 新添加控件以後,編譯一下,對應的 strings 文件會增長新控件的 key-value 對,而刪除的控件的的 key-value 對會被註釋
以後有空會補上
AutoGenStrings.py
的解讀,參考的腳本原先只有 storyboard 的處理,這裏擴展至 xib
NSLocalizedString(key, comment)
中 comment 參數的使用第一個參數是:key的名字 第二個參數是:對這個「鍵值對」的註釋,在用
genstrings
工具生成Localizable.strings文件時會自動加上去
通常狀況下,語言翻譯的操做並非咱們程序員源來作的(~固然,nb的猿都會nb地接手這些工做~),那麼怎樣纔可以將語言本地化strings文件分發出去同時又可以很好的按流程工做呢?
NSLocalizedString
進行臆想本地化實現NSLocalizedString
的查找邏輯,key 不存在時直接返回 key 值genstrings
將使用了NSLocalizedString
的viewController.m
文件,生成對應語言環境的 strings 文件NSLocalizedString
修改好以後,就能夠動用genstrings
工具了mkdir zh-Hans.lproj
mkdir en.lproj
複製代碼
推薦經過 Xcode 幫咱們生成,參考文章 「第1點:添加要支持的國際語言」,這樣你還能夠省去語言簡寫目錄名的煩惱,直接從 Xcode 中選擇你想要支持的國際語言
選擇語言
生成的.lproj
文件夾
發現沒有 en.lproj
文件夾,不要緊,點選 main.storyboard
,在文件的 localize 位置勾上 English 選項,同理 launch.storyboard
也一樣操做
出現了 en.lproj
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
等。
genstrings -o zh-Hans.lproj *.m
命令以後,對應的zh-Hans.lproj
文件夾多了Localizable.strings
,其餘同理
生成Localizable.strings
文件都拖拽到工程中,Xcode會自動合併成一個,而且對應生成的內容是按照前面NSLocalizedString(@"home", @"這個是用來在生成 strings 文件時,在對應的 key-value 行上的註釋,用來提示翻譯員或者猿們的相關提示")
生成的。
以後咱們將這些文件分發到翻譯員(~或者你本身手裏~)
注意:
genstrings
指令只能是該目錄下的文件遍歷,但不能實現遞歸遍歷,要實現遞歸變量,可使用下述命令find ./ -name *.m | xargs genstrings -o en.lproj
這是shell組合指令find+xargs
,find ./ -name *.m
會遞歸全部.m
文件並存在一個數組中,這個數組經由pipe
傳遞給了下一個指令,而xargs
會將收到的數組一一分割,並交給genstrings執行。
#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)]
複製代碼
LanguageLocalizationDemo - 第1-7點使用
LocalizationGenStringsDemo - 第8點使用
文/Jacob_LJ(掘金做者)
PS:如非特別說明,全部文章均爲原創做品,著做權歸做者全部,轉載需聯繫做者得到受權,並註明出處,全部打賞均歸本人全部!