
Good code is its own best documentation. As you're about to add a comment, ask yourself, "How can I improve the code so that this comment isn't needed?" Improve the code and then document it to make it even clearer.
- Steve McConnell
在本章中,我們將介紹「本地化」(Localization )。iOS 裝置(包括iPhone 與iPad )在世界各地都可以取得,而 App Store 在全球 150 多個國家都可下載,你的使用者來自不同的國家,說著不同的語言,要提供絕佳的使用者體驗並吸引全球的使用者,你需要讓你的 App 能夠支援多種語言,而調整 App 來支援一個特定語言的過程,一般稱為「本地化」。
Xcode 已經內建支援本地化,它讓開發者很容易透過「本地化」功能與一些 API 的呼叫來進行本地化 App。
你可能聽過這兩個名詞:「本地化」與「國際化」,你也許認為這是指翻譯過程,有部分是正確的,在 iOS 程式開發中,「國際化」(Internationalization )是建置本地化 App 的里程碑。為了讓你的 App 能夠順應不同的語言,App 設計架構中涉及語言及地區差異的部分必須獨立出來,這便是所謂的「國際化」。舉例而言,如果你的App 需要顯示價格欄位,則已知某些國家是用「句點」來代表小數點(例如:$1000.50),而某些國家則是使用「逗點」(例如:$1000,50),因此對這個 App 做國際化的具體過程,便需要將價格欄位設計成可順應不同的地區。
至於本地化,則是 App 經過國際化後再進一步支援多種語言及地區的具體過程,這個過程包含對靜態及可見文字的特定語言翻譯,並加上對於特定國家的元素,例如:圖片、影片及聲音等。
在本章中,我們將會本地化 FoodPin App 為中文及德文,但不要期望我會翻譯 App 中的所有文字,我只是想教導你使用 Xcode 實作本地化的程序。
隨著 Xcode 15 的發布,Apple 導入了一個令人興奮的功能,名為「字串目錄」(String Catalogs ),這個功能旨在簡化 App 的本地化程序,讓你能夠比以往更輕鬆地在一個中心位置管理所有字串。利用字串目錄,您可以確保App 在發布給用戶之前已經完全本地化, 這個新功能為本地化過程提供了便利與信心。
在我們繼續實作之前,我們來檢查一下 App 中面向使用者( user-facing )的文字。原始碼中有大量的面向使用者的文字,例如:「New Restaurant」表單中顯示的文本欄位。圖 24.1 展示了在 NewRestaurantView 結構中面向使用者的文字的一些範例。
在 Xcode 的早期版本中,你必須經歷字串國際化的程序,這需要使用 String(localized:) 巨集修改現有的文字,然而隨著字串目錄的導入,就不再需要這個程序了,字串目錄會自動為你取出所有面向使用者的文字,而無須手動修改。

目前你的 App 只支援英文,若要支援其他語言,則在專案導覽器中選取「FoodPin」專案,然後選擇「Info」,並在 PROJECT 區塊下選擇「FoodPin」。要加入其他語言,則在 Localizations 區塊下點選「+」按鈕,選擇你想要支援的語言,對於這個示範,我們選擇「Chinese(Traditional)(zh-Hant)」,如圖 24.2 所示。

選擇所需的語言後,你會看到「Chinese, Traditional」語言已經加入 Localizations 區塊中。你可以重複相同的過程,依據需要增加更多語言來支援它們。對於這個 App 而言, 除了中文之外,我們還將支援德文,因此依照前面提到的步驟來加入「German」語言到你的專案中。
加入支援的本地化後,我們必須手動增加一個 String Catalog 檔案。在專案導覽中, 在「FoodPin」資料夾上按右鍵,並選擇「New File...」,然後在 iOS 類別下尋找「String Catalog」模板,點選「Next」按鈕繼續,將檔案名稱命名為「Localizable」。

這個程序會產生一個空的 Localizable 檔案,其中包含你的 App 支援的所有語言。要將所有面向使用者的文字取出至此檔案中,你可以按照下列步驟操作:從Xcode 選單中選擇「Product」,然後選擇「Build」重建專案。建立過程完成後,Xcode 會自動取出所有文字,並將其填入 Localizable 檔案中。

取出文字後,你可以直接在 String Catalog 檔案中為每種語言加入翻譯,這讓讓你可以提供文字的本地化版本,並確保 App 針對不同的語言進行了正確的本地化。
測試 App 本地化有幾種方式,其中一種方式是變更模擬器的語言偏好設定,然後執行這個本地化 App,以讓你檢視 App 在不同語言下的表現。另一個選項是利用 Xcode 中的「預覽」功能,讓你在執行期與介面建構器中以各種的語言與區域測試你的 App,我們來詳細探討這些選項。
要在 Xcode 中啟用執行期預覽功能,你可以修改架構表,並在架構設定中,你可在對話方塊中設定你的偏好語言,以讓你預覽 App 在該特定語言下的顯示及功能,如圖 24.5 所示。

在對話方塊中,選擇「Run → Options」,並將「App Language」選項變更為你的偏好語言,例如:選擇「Chinese, Traditional」,然後點選「Close」按鈕來儲存設定,如圖 24.6 所示。

現在點擊「Run」按鈕來啟動 App,模擬器的語言應設定為你的偏好語言。若是你將其設定為「Chinese / German」,你的 App 看起來應該如圖 24.7 所示。

要預覽 SwiftUI App 的本地化,你可以利用預覽程式碼中的 locale 環境變數,這可讓你以不同語言模擬 App 的 UI。舉例而言,如果你想要以德語預覽 App UI,則你可以加入具有所需的本地化設定的額外預覽程式碼區塊。以下是一個例子:
#Preview("AboutView (German)") {
AboutView()
.environment(\.locale, .init(identifier: "de"))
}
透過將 locale 環境變數設定為「.init(identifier: "de")」,你可以預覽德語本地化的 App UI。你可以根據需要修改識別碼來模擬其他語言。

在 Localizable 檔案中,有一個註解欄位會顯示每個鍵和翻譯的關聯註解。如果你想要為特定鍵加入註解,則可以在定義 Text 視圖時包含它們,如下所示:
Text("Sorry, this feature is not available yet. Please retry later.",
comment: "The message displayed when a user selects to place a call to the restaurant.")
當你使用註解修改程式碼後,它就會出現在 Localizable 檔案中。

你可能會注意到一些文字不會自動取出到 Localizable 檔案中,例如:NewRestaurant View 的文字欄位沒有本地化:
FormTextField(label: "NAME", placeholder: "Fill in the restaurant name", value: $restaurantFormViewModel.name)
FormTextField(label: "TYPE", placeholder: "Fill in the restaurant type", value: $restaurantFormViewModel.type)
要讓這些文字可本地化,你可以使用 String(localized:) 初始化器來修改程式碼,如下所示:
FormTextField(label: String(localized: "NAME"), placeholder: String(localized: "Fill in the restaurant name"), value: $restaurantFormViewModel.name)
FormTextField(label: String(localized: "TYPE"), placeholder: String(localized: "Fill in the restaurant type"), value: $restaurantFormViewModel.type)
在重建專案後,這些文字就會被整合到 Localizable 檔案中。

在本章中,我介紹了 Xcode 中的本地化程序。Xcode 15 導入字串目錄,大大簡化了開發者的工作流程,這個新功能可自動從 SwiftUI 視圖中取出文字,並將它們合併到一個集中檔案中。此外,翻譯人員可以直接在 Xcode 中方便地編輯譯文,從而簡化了本地化過程。
請記得 App 的市場遍佈全球,使用者更喜愛擁有他們的語言的 App UI,透過本地化你的 App ,你將能夠提供絕佳的使用者體驗,並吸引更多的下載。
在本章所準備的範例檔中,有最後完整的 Xcode 專案可供你下載參考: http://www.appcoda.com/resources/swift59/swiftui-foodpin-localization.zip 。