iOS 已經包含了一個系統範圍的翻譯功能,允許用戶輕鬆地將文本翻譯成各種語言。隨著 iOS 17.4(以及 iOS 18)的發布,你現在可以利用新的 Translation API 將這個強大的翻譯功能整合到你的應用中。
Apple 為開發者提供了兩種使用 Translation API 的選擇。最快且最簡單的方法是使用 .translationPresentation
修飾器,它會在你的應用中顯示一個翻譯覆蓋層。對於更靈活的解決方案,你可以直接調用 Translation API 來構建自定義的翻譯功能。
在本教程中,我們將探討這兩種方法,並通過一個簡單的示例應用來引導你實現它們。請注意,你需要 Xcode 16 來跟隨本教程。
使用 translationPresentation 修飾器
讓我們從最簡單的方法開始:.translationPresentation
修飾器。在 Safari 中,用戶可以突出顯示任何文本以訪問翻譯選項,然後顯示帶有翻譯文本的翻譯覆蓋層。
如果你想將這個翻譯覆蓋層帶到你的應用中,你只需導入 Translation
包並使用 .translationPresentation
修飾器。請查看以下示例程式碼:
import SwiftUI
import Translation
struct ContentView: View {
@State private var showTranslation = false
@State private var sampleText = article
var body: some View {
VStack {
Text(sampleText)
.font(.system(.body, design: .rounded))
Button("Translate") {
showTranslation.toggle()
}
.controlSize(.extraLarge)
.buttonStyle(.borderedProminent)
}
.padding()
.translationPresentation(isPresented: $showTranslation, text: article)
}
}
此 app 顯示了一些英文示例文本,並在其下方放置了一個 Translate 按鈕。
現在,當你點擊「Translate」按鈕時,將顯示一個翻譯覆蓋層,顯示所需語言的翻譯文本。除了 iOS 之外,Translation API 也適用於 iPadOS 和 macOS。目前,這個翻譯功能不能在 Xcode 預覽中測試;你必須將應用部署到真實設備上進行測試。
.translationPresentation
修飾器允許你指定當用戶點擊「Replace with Translation」按鈕時要執行的可選操作。例如,如果你希望在按下按鈕時將原始文本替換為翻譯文本,你可以像這樣定義此操作:
.translationPresentation(isPresented: $showTranslation, text: article) { translatedText in
sampleText = translatedText
}
一旦你在修飾器中指定了操作,你將在翻譯覆蓋層中看到「Replace with Translation」選項。
使用 Translation API
為了更好地控制翻譯,你可以直接使用 Translation API,而不是依賴翻譯覆蓋層。例如,如果你的應用程式顯示了一個文章摘錄列表,並且你想提供翻譯支援,翻譯覆蓋層可能並不理想,因為用戶必須逐個選擇每個摘錄進行翻譯。
一種更有效的解決方案是當使用者點擊「Translate」按鈕時,執行所有文章摘錄的批次翻譯。讓我們創建一個簡單的示範,看看如何使用翻譯 API 並處理批次翻譯。
下面是創建上述 UI 的範例程式碼:
struct BatchTranslationDemo: View {
@State private var articles = sampleArticles
var body: some View {
NavigationStack {
List(articles) { article in
VStack {
Text(article.text)
if article.translatedText != "" {
Text(article.translatedText)
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
.background(Color(.systemGray4))
}
}
}
.listStyle(.plain)
.toolbar {
Button {
} label: {
Label("Translate", systemImage: "translate")
.labelStyle(.iconOnly)
}
}
}
}
}
要執行批次翻譯,首先需要定義一個翻譯配置,該配置指定來源語言和目標語言。在程式碼中,你可以宣告一個狀態變數來保存配置,如下所示:
@State private var configuration: TranslationSession.Configuration?
然後,在工具列的 Button
的閉包中,我們可以實例化該配置:
Button {
if configuration == nil {
configuration = TranslationSession.Configuration(source: .init(identifier: "en-US"), target: .init(identifier: "zh-Hant-TW"))
return
}
configuration?.invalidate()
} label: {
Label("Translate", systemImage: "translate")
.labelStyle(.iconOnly)
}
我們指定英語為來源語言,繁體中文為目標語言。如果你不指定語言,翻譯 API 將自動創建一個預設配置,由 iOS 確定來源語言和目標語言。
要執行翻譯,你需要將 .translationTask
修飾器附加到列表視圖:
List(articles) { article in
.
.
.
}
.translationTask(configuration) { session in
let requests = articles.map { TranslationSession.Request(sourceText: $0.text, clientIdentifier: $0.id.uuidString) }
if let responses = try? await session.translations(from: requests) {
responses.forEach { response in
updateTranslation(response: response)
}
}
}
這個修飾器使用指定的配置啟動一個翻譯任務。每當配置發生變化且不為 nil
時,翻譯任務就會執行。在閉包內,我們準備一組翻譯請求,並使用會話的 translations(from:)
方法執行批次翻譯。
如果翻譯任務成功,它會返回一個包含翻譯文本的翻譯回應陣列。然後我們將該翻譯文本傳遞給 updateTranslation
方法,以顯示在螢幕上。
func updateTranslation(response: TranslationSession.Response) {
guard let index = articles.firstIndex(where: { $0.id.uuidString == response.clientIdentifier }) else {
return
}
articles[index].translatedText = response.targetText
}
讓我們將應用程式部署到真實裝置進行測試。我在我的 iPad Air 上測試了該應用程式。當你點擊「翻譯」按鈕時,應用程式應顯示繁體中文的其他文章摘錄。
總結
隨著 iOS 17.4(以及 iOS 18)引入的新翻譯 API,開發者現在可以輕鬆地將強大的翻譯功能整合到他們的應用程式中。本教程涵蓋了兩種主要方法來使用該 API:使用 .translationPresentation
修飾器顯示翻譯覆蓋的簡單方法,以及直接使用翻譯 API 進行自訂翻譯解決方案的更靈活方法。
我們在本教程中演示了這兩種方法。如示範中所示,只需幾行程式碼,你就可以輕鬆添加翻譯功能。鑑於該 API 的簡單性和強大性,沒有理由不在你的應用程式中包含翻譯功能。