Localization - 讓 App 支援不同語言 手把手教學

更新於 發佈於 閱讀時間約 8 分鐘

身為一個菜鳥工程師,將辛苦製作的 App 推向國際,多國語言是肯定要的。Let’s Go Go Go!

專案設定

打開專案內的 Project -> Info -> Localizations 新增你想要增加的語言

raw-image

增加完後會問你要添加的地方,例如 Main.storyboard 打勾的話,就會幫你把 storyboard 中所有有文字的地方變成一串 key = value 的形式,放進 main.strings 檔案,這個檔案會在你添加的語言資料夾內,所以每加一個語言,就會有一個專屬的資料夾

raw-image
en 的語言資料夾內

en 的語言資料夾內

storyboard 多國語文檔

Main 底下會長出語言的檔案

Main 底下會長出語言的檔案

raw-image

左圖可以看到,"2Gf-sf-0bs.text" = "Password"; 2Gf-sf-0bs這串文字其實是該 label 的 objectID,也是讓程式尋找對應的文字的 Key ,所以如果不知道這邊的文字代表畫面上哪個物件的時候,可以用 objectID 去 stroryboard 確認是哪個物件


在 stroryboard 上點選物件後,Document 欄位會有 objectID


這時候就會想到,阿如果我有些文字是用程式產生的呢?




程式中的文字多國語文檔

新增 Strings File,取名為 Localizable(請務必這樣取名,方便Xcode抓取),接著點選檔案右側的 Localization 將需要的語言打勾,就會幫你產出好幾個檔案

raw-image
raw-image

這邊的 Key 命名就看個人習慣,自己是將不同類型的文字前面加上label, btn, alert … 等作區分

記得程式內有使用到 String 文字的地方,就要透過 Key 去讀取對應的 String,才能達到多國語系顯示的目的

App Name 多國語文檔

別忘了幫 App 的大名跟著一起切換,這時候又要新增一個 Strings File,然後 key 為 "CFBundleDisplayName" 記得一定要取這個 Key 不然系統會抓不到

raw-image

應用時間

// Localizable.string 內的格式
"alert_logInSuccess" = "LogIn Success";
"label_amountOfDiamondsText" = "%d 顆鑽石"; // %d 的地方可以傳入參數

// controller 讀取
let logInSuccessText = NSLocalizedString("PurchaseVC.Alert.logInSuccess", comment: "logIn Success")

let amountOfDiamondsText = NSLocalizedString("PurchaseVC.Label.amountOfDiamondsText", comment: "amountOfDiamondsText")
label.text = String.localizedStringWithFormat(amountOfDiamondsText, amountOfDiamonds) // print 1,000 顆鑽石
  • 直接透過 Key 讀取
    單純讀取文字的時候透過 NSLocalizedString("文字對應的KEY", comment: "這邊可以為空,也可以寫這個文字的意思")
  • 讀取的內容需要傳入參數
    遇到在數值前後的文字,可以在要轉換的文字中加上 %d,透過NSLocalizedString 取得文字,再透過 String.localizedStringWithFormat(文字, 數值) 就能完美讀取有數值的文字拉
  • Enum 讀取字串
enum ProductID: String, CaseIterable {
case diamonds100 = "Item01"
case aiChatfor1Week = "Item06"

var productName: String {
switch self {
case .diamonds100:
return NSLocalizedString("diamonds100", comment: "diamonds100")
case .aiChatfor1Week:
return NSLocalizedString("aiChatfor1Week", comment: "aiChatfor1Week")
}
}

// Localizable.string 內
"diamonds100" = "100 顆鑽石"
"aiChatfor1Week" = "AI 聊天/ 週";

小撇步

  • enum 定義 Key 不容易打字錯誤
enum LocalizedKey: String { 
case label_greeting, label_amountOfDiamondsText, btn_logIn, btn_logOut, alert_noRestore, alert_restoreSuccess, alert_cantBuy, alert_productName, alert_pleaseLogIn, alert_accountNPass 
case label_psw, label_account, label_language, label_thrLogIn, label_welcome, label_server, label_buyDiamond, btn_restore, label_system 

var str: String { self.rawValue }
}
  • String Extension
extension String {

var localizable: String {
// 吃 LanguageManager 被賦予的 languageType
if let manager = LanguageManager.shareInstance() as? LanguageManager,
let path = Bundle.main.path(forResource: manager.languageType, ofType: "lproj"), let bundle = Bundle(path: path) {
return NSLocalizedString(self, tableName: nil, bundle: bundle, value: "", comment: "")
}
return self
}
}

// Localizable file
"memberCenter" = "會員中心";

// call
mylabel.text = "memberCenter".localizable


實作過後分享,Main.strings 的小缺點:
如果有新增的頁面或新增的 label or button,自己手動加 objectID 進去 Main.string 檔案後系統還是會吃不到,我的方式會最後才建立多國語言這個步驟,或是將要新增的文字直接加去 Localizable.strings 內,再拉 label or button 的 IBOutlet 進 ViewController,將文字指派給他


下一篇介紹如何包裝寫成一個完整的 LanguageManager 🤩


參考其他大大文章

在 APP 內切換語系(iOS Localized)

【iOS】#31 多語系設定 Localization

Swift之本地国际化与App内切换语言

留言0
查看全部
avatar-img
發表第一個留言支持創作者!
咻咻回家發現行車紀錄器壞了,噴了三千大洋換mio小姐,以後就麻煩她報測速了,還被車廠維修先生假撩妹真詐財,幸好我識破了他的伎倆😎 晚上跟卓寶去看咒術迴戰,好好看!!!純愛好感動,最喜歡狗卷,喜歡到不行,鮭魚❤️ 可能是阿月要來了
其實這兩週都沒什麼約會,唯一大的起伏是詩梵真的要飛往英國了,一直覺得很遙遠的事突然在眼前,好不真實的感覺
咻咻回家發現行車紀錄器壞了,噴了三千大洋換mio小姐,以後就麻煩她報測速了,還被車廠維修先生假撩妹真詐財,幸好我識破了他的伎倆😎 晚上跟卓寶去看咒術迴戰,好好看!!!純愛好感動,最喜歡狗卷,喜歡到不行,鮭魚❤️ 可能是阿月要來了
其實這兩週都沒什麼約會,唯一大的起伏是詩梵真的要飛往英國了,一直覺得很遙遠的事突然在眼前,好不真實的感覺
你可能也想看
Google News 追蹤
Thumbnail
/ 大家現在出門買東西還會帶錢包嗎 鴨鴨發現自己好像快一個禮拜沒帶錢包出門 還是可以天天買滿買好回家(? 因此為了記錄手機消費跟各種紅利優惠 鴨鴨都會特別注意銀行的App好不好用! 像是介面設計就是會很在意的地方 很多銀行通常會為了要滿足不同客群 會推出很多App讓使用者下載 每次
Thumbnail
這篇內容,將教你如何開啟新的GameMaker專案,並調整畫面佈局。也會講解,為何建議用英文語系,來進行遊戲開發。
Thumbnail
這篇內容,將教你如何安裝GameMaker,並更改語言設定。包括GameMaker的下載說明、版本說明、安裝說明、語系更改。
Thumbnail
這篇文章描述了作者從兼職開發轉為全職開發的過程,並分享了從混進學界指日可待的積極態度。作者也提及自己在專案製作與個人生活上的矛盾與感想,最後分享了專案管理和敏捷開發相關的文章與影片。
Thumbnail
Duolingo是一個受歡迎的語言學習應用程序,通過遊戲化的方式提供30種語言的課程,並且使用成就係統、排行榜和每日目標等功能來激勵用戶保持學習動力,充分滿足不同用戶的學習需求。此外,該應用程序還提供了捏臉、牌位和複習輔助等有趣功能。
Thumbnail
哈囉你們好!我是Chloe,2月很幸運跟朋友一起去了趟日本!在遊玩迪士尼的時候真的研究了很久呢!由於網路上有太多的迪士尼攻略還有使用教學了,這邊就簡單分享APP的註冊與切換語言,不會示範APP的操作唷
Thumbnail
學習語言除了練習,一定要有適當的環境,才能事半功倍。
我目前會10種語言:中英日俄韓法德西義波。 其中,中英日是不用看字幕也能聽懂的程度, 俄韓法義還在建立語感,德西波則還在基礎單字的等級。 會學這麼多種語言,起源於我在2020年28歲時開始學義大利語。 當初學義大利語的目的,是準備到義大利的西西里島, 參加機器學習會議
Thumbnail
單語者是使用或通曉一種語言的人,通常為母語;多語者是使用或通曉多國語言的人,除了母語,還包括其他外語。
Thumbnail
台灣市場規模不夠的先天不足,加上網際網路有打破地理限制的特性,在我從事系統開發以來,出資人或是產品經理在發展數位產品時,常會希望系統能夠觸及全世界各地的使用者。衍生的就是系統需要能夠全球化、在地化的需求。然而這不僅僅是一個關於語言轉換的問題,而是一個涉及技術、法律以及市場策略等多維度的問題。
Thumbnail
/ 大家現在出門買東西還會帶錢包嗎 鴨鴨發現自己好像快一個禮拜沒帶錢包出門 還是可以天天買滿買好回家(? 因此為了記錄手機消費跟各種紅利優惠 鴨鴨都會特別注意銀行的App好不好用! 像是介面設計就是會很在意的地方 很多銀行通常會為了要滿足不同客群 會推出很多App讓使用者下載 每次
Thumbnail
這篇內容,將教你如何開啟新的GameMaker專案,並調整畫面佈局。也會講解,為何建議用英文語系,來進行遊戲開發。
Thumbnail
這篇內容,將教你如何安裝GameMaker,並更改語言設定。包括GameMaker的下載說明、版本說明、安裝說明、語系更改。
Thumbnail
這篇文章描述了作者從兼職開發轉為全職開發的過程,並分享了從混進學界指日可待的積極態度。作者也提及自己在專案製作與個人生活上的矛盾與感想,最後分享了專案管理和敏捷開發相關的文章與影片。
Thumbnail
Duolingo是一個受歡迎的語言學習應用程序,通過遊戲化的方式提供30種語言的課程,並且使用成就係統、排行榜和每日目標等功能來激勵用戶保持學習動力,充分滿足不同用戶的學習需求。此外,該應用程序還提供了捏臉、牌位和複習輔助等有趣功能。
Thumbnail
哈囉你們好!我是Chloe,2月很幸運跟朋友一起去了趟日本!在遊玩迪士尼的時候真的研究了很久呢!由於網路上有太多的迪士尼攻略還有使用教學了,這邊就簡單分享APP的註冊與切換語言,不會示範APP的操作唷
Thumbnail
學習語言除了練習,一定要有適當的環境,才能事半功倍。
我目前會10種語言:中英日俄韓法德西義波。 其中,中英日是不用看字幕也能聽懂的程度, 俄韓法義還在建立語感,德西波則還在基礎單字的等級。 會學這麼多種語言,起源於我在2020年28歲時開始學義大利語。 當初學義大利語的目的,是準備到義大利的西西里島, 參加機器學習會議
Thumbnail
單語者是使用或通曉一種語言的人,通常為母語;多語者是使用或通曉多國語言的人,除了母語,還包括其他外語。
Thumbnail
台灣市場規模不夠的先天不足,加上網際網路有打破地理限制的特性,在我從事系統開發以來,出資人或是產品經理在發展數位產品時,常會希望系統能夠觸及全世界各地的使用者。衍生的就是系統需要能夠全球化、在地化的需求。然而這不僅僅是一個關於語言轉換的問題,而是一個涉及技術、法律以及市場策略等多維度的問題。