demo
- storyboard中的文字
- 代碼中的文字
- app名稱的展示
- 資源文件的國際化
- 國際化腳本
國際化原理
核心思想就是為每種語言單獨(dú)定義一份資源。
iOS就是通過xxx.lproj目錄來定義每個(gè)語言的資源酸茴,這里的資源可以是圖片分预,文本,Storyboard薪捍,Xib等笼痹。
每種語言都有自己的 語言代碼.lproj文件夾配喳,加載資源時(shí)只需要加載相應(yīng)語言文件夾下的資源就OK
例如:根目錄下英語的為en.lproj,中文的為zh-Hans.lproj凳干。
國際化過程
- 首先添加國際化配置
- 選中project->Info->Localizations晴裹,然后點(diǎn)擊"+",添加需要國際化/本地化的語言救赐,如下圖(默認(rèn)需要勾選Use Base Internationalization)
圖片引用于:VV木公子 - 點(diǎn)擊+后涧团,選擇后綴為Chinese (Simplified)(zh-Hans)簡體中文,后綴為(zh-Hant)為繁體中文经磅。
- 在這說一句后綴問題泌绣,所有iOS支持的語言及后綴,都可以在點(diǎn)擊+后出現(xiàn)的語言中找到预厌,其中最下面的other下是全部的集合阿迈。其中英語的后綴為(en)
- 選中project->Info->Localizations晴裹,然后點(diǎn)擊"+",添加需要國際化/本地化的語言救赐,如下圖(默認(rèn)需要勾選Use Base Internationalization)
- 應(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待逞,目的是選擇我們需要本地化的語言 如下圖:
點(diǎn)擊Localize后,在彈出框中->點(diǎn)擊base->展開的列表中選擇English->隨后選中右下角的Localize
-
此時(shí)右側(cè)會(huì)變成下圖模樣腰埂,勾選Chinese
-
此時(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)限聲明國際化
- 代碼中字符串的本地化
- 與上類似,創(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)語言的
- 多人開發(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];
- 上面介紹的代碼中字符串的本地化是使用的是默認(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#>)的用處遍尺。
- 圖片本地化
- 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)的圖片
- 查看/切換本地語言
- 應(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賦值
- 還有一種方式如下圖
- app內(nèi)的語言切換。一個(gè)App切換語言的Demo
- 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" = "國際化測試";
- 腳本
- iOS項(xiàng)目中處理國際化文件數(shù)據(jù)導(dǎo)入導(dǎo)出腳本
- 這個(gè)腳本readme.md在介紹時(shí)有些地方不是最新版躺苦,要記得微調(diào)。例如第二版的:---.py的名字
- 這個(gè)腳本適用于要適配很多個(gè)語言产还,每個(gè)語言有很多項(xiàng)
-
第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
- 如果你最開始就在代碼中已經(jīng)預(yù)先設(shè)置了NSLocalizedString(@"使用幫助", nil)類似的字段坡椒,只差生成對應(yīng)的key-value時(shí),你可以
-
如果你什么也沒配置倔叼,就是簡單的將相關(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)的碘耳,請查看字符串本地化這篇介紹显设。
- 首先你需要全局替換需要配置的中文字符,并以已經(jīng)設(shè)置的中文字符為key
-
第二項(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}
-
Build Setting -> Deployment -> Deployment Location / Deployment Postprocessing -> Yes
注意文件路徑中不能擁有空格狞山,否則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字段列表,很全