Apple 的 Translation 框架:免費、裝置端執行,而且比表面更銳利
Apple 的 Translation 框架在裝置端翻譯文字,完全免費,不需要 API 金鑰,語言安裝完成後也不需要任何網路呼叫1。它建構於 Core ML 模型之上,隨系統一同出貨,讓應用程式得以使用與「翻譯」App 相同的翻譯引擎。對於那些過去意味著雲端翻譯帳單與隱私疑慮的多語言功能來說,成本再一次趨近於零。而如同 Foundation Models 框架,真正有意思的並非一帆風順的流程,而是示範略過的那些邊角:會阻擋您第一次翻譯的語言下載、在模擬器上默默拒絕運作,以及僅限 SwiftUI 的介面如何形塑您採用它的方式。
重點摘要
- 兩種介面,兩個 iOS 版本。
translationPresentation會顯示 Apple 內建的翻譯彈出視窗(iOS 17.4 以上)。TranslationSession透過translationTask修飾器取用,可在您自己的 UI 中進行程式化翻譯(iOS 18 以上)2。 - 程式化翻譯是
async的。 在translationTask閉包內,您會取得一個TranslationSession;呼叫它即可翻譯單一字串或一整批3。 - 批次處理是一等公民。 在單一請求中翻譯一份清單,並讓每筆結果都對應到各自的輸入,而不必逐筆迴圈、逐筆等待3。
- 翻譯 UI 僅限 SwiftUI,而且無法在 iOS 模擬器中執行。 這兩點都很容易在踩雷後才發現;請據此設計與測試4。
- 離線意味著要先下載。 某個語言配對的第一次翻譯會下載語言套件,這是您需要妥善處理的真實 UX 環節,而非小細節5。
- 值得記住的搭配:先用 Translation 翻譯使用者輸入,再用 Foundation Models 對其推理,於是一個單語的裝置端代理功能,便能在裝置可安裝的任何語言中運作。
兩種介面:系統彈出視窗,以及您自己的 UI
這個框架提供兩種截然不同的翻譯方式,而選對其中之一,就是決策的大半。
輕量的選擇是 translationPresentation,自 iOS 17.4 起可用。您把它附加到一個視圖上,綁定一個 isPresented 旗標並傳入文字;當旗標翻為 true 時,系統便會在您的內容之上滑出它自己的翻譯彈出視窗2:
.translationPresentation(isPresented: $showTranslation, text: selectedText)
您不需撰寫任何翻譯邏輯,也看不到結果;UI 與互動皆由 Apple 掌控。對於「讓使用者翻譯這段文字」這類需求,這就是功能的全部,再去動用任何更重的東西都是白費工夫。
程式化的介面是 TranslationSession,自 iOS 18 起可用,您透過 translationTask 修飾器來取用它。該修飾器會執行一個非同步閉包,並交給您一個由您親自呼叫的工作階段,於是翻譯後的文字會回到您的程式碼中,由您以自己的方式呈現2:
.translationTask(configuration) { session in
let response = try await session.translate("Good morning")
await MainActor.run { translated = response.targetText }
}
分工清楚分明。translationPresentation 用於在 Apple 的 UI 中向使用者展示翻譯。TranslationSession 則用於把翻譯後的文字帶進您的資料與您的視圖。多數不只做一次性「翻譯這個」的應用程式,都會選擇工作階段。
批次翻譯:翻譯整份清單,而非用迴圈
讓功能流暢與卡頓拉開差距的細節在於批次處理。若您需要翻譯一份清單(聊天訊息、目錄項目、一組標籤),別用迴圈逐筆 await 翻譯。TranslationSession 可接收一批請求,並在單次處理中回傳各自對應請求的回應3:
.translationTask(configuration) { session in
let requests = items.map { TranslationSession.Request(sourceText: $0.text, clientIdentifier: $0.id) }
for try await response in session.translate(batch: requests) {
store[response.clientIdentifier] = response.targetText
}
}
關鍵在於 clientIdentifier:它會隨回應一併回傳,讓您無須仰賴順序,就能將每筆翻譯對應到它所屬的列。批次處理也讓框架得以有效率地排程工作,而非在迴圈中付出逐次呼叫的開銷。只要超過單一字串,就用批次。
沒人截圖的離線真相
這裡有個能讓乾淨示範變成客服工單的邊角。翻譯在裝置端執行,但語言必須先在裝置上。您的應用程式第一次翻譯某組來源到目標的配對時,系統會下載語言套件,而這個下載需要時間與網路連線5。若您觸發翻譯卻沒有為下載做任何處理就直接呈現結果,那麼對每一種新語言而言,您的功能在首次使用時都會看似當機。
請刻意處理它。框架讓您能檢查語言可用性,並在需要的時刻之前先準備(下載)一組配對,於是您可以呈現一個「正在準備翻譯」的狀態,或在較從容的時機預先下載,而非在互動進行到一半時卡住5。心智模型是這樣:把某個語言配對的第一次翻譯,當成一次性的資源下載來看待,因為它本來就是。圍繞「下載確實存在」這件事去規劃 UX,離線又免費的好處便能落地;忽略它,這份好處就藏在當機背後。
還有兩個事實,若太晚才學到會耗掉您一個下午。翻譯 UI 介面都是 SwiftUI 修飾器,因此一個 UIKit 畫面得透過 UIHostingController 寄載一個 SwiftUI 視圖才能取用它們;不過 TranslationSession 也能直接建構出來,用於無 UI 的工作4。此外,這個框架無法在 iOS 或 iPadOS 模擬器中執行;您得在實機上測試翻譯4。這兩點都沒有被大聲記載,卻都很容易迎面撞上。
將翻譯與 Foundation Models 搭配
值得帶走的綜合心得,把這個框架繫回裝置端技術堆疊的其餘部分。多數裝置端的語言工作,都假設輸入是您的邏輯與系統模型能妥善處理的語言。但真實的使用者不會配合。Translation 框架彌合了這道落差:把使用者的輸入翻譯成您功能用以推理的語言,在翻譯後的文字上執行 Foundation Models 的工作,再把結果翻譯回去。
整個形狀像一個括號:翻入、推理、翻出。
// 1. translate the user's text into English (session configured for their language -> en)
let english = try await inboundSession.translate(userText).targetText
// 2. reason on-device, monolingually, in English
let summary = try await LanguageModelSession()
.respond(to: "Summarize in one line: \(english)").content
// 3. translate the result back (a session configured for en -> their language)
let localized = try await outboundSession.translate(summary).targetText
一個客服分流功能、一個筆記摘要器、一個意圖擷取器:每一個都只需以單語撰寫一次,再透過用 Translation 把 Foundation Models 呼叫括起來,便能在裝置可安裝的任何語言中運作。兩個方向使用兩套工作階段設定(他們的語言轉成英文,然後英文再轉回去),因為一個工作階段只設定為一組語言配對。兩個層次都在裝置端,兩者都免費,沒有任何東西離開手機,於是這個多語言版本不會比單語版本多付出任何隱私代價或雲端帳單。那種組合(翻入、推理、翻出)正是讓一個小巧的裝置端功能真正走向全球的模式,而它之所以可行,正因為兩半都在本機免費執行。
何時不該用它
裝置端翻譯免費又私密,這使它成為應用程式內翻譯的合理預設。但在幾個誠實的情境裡,它是錯的工具。
- 您需要最佳的翻譯品質,或最廣的語言覆蓋。 裝置端模型很好,但不是現有最佳,可安裝的語言集也是有限的。對於高風險翻譯(法律、醫療、出版內容),專屬的雲端翻譯服務在品質與廣度上仍然勝出。
- 您無法容忍首次使用的下載。 對於一個必須在首次啟動、無網路的情況下立即運作的功能,下載要求本身就可能讓裝置端翻譯出局,除非您在引導流程中預先下載。
- 您的應用程式是 UIKit 且沒有空間容納 SwiftUI 寄載,或您的流程必須在模擬器中執行(例如一個自動化 UI 測試)。僅限 SwiftUI 與無法在模擬器執行這兩項限制是硬性的,而非建議性的。
這個框架是裝置端工具箱裡較安靜的勝利之一:一個真正免費又私密的翻譯引擎,多數應用程式都能在一個下午內採用。所需的本領,與這整套技術堆疊其餘部分所獎賞的是同一種。知道哪個介面合適(系統彈出視窗,或您自己的工作階段),有清單時就用批次,並且為下載而設計,而非假裝它不存在。做到這些,翻譯就不再是一項雲端相依,而成為一項您能與裝置免費為您做的一切相互組合的本機能力。
常見問題
Apple 的 Translation 框架是免費且裝置端執行的嗎?
是的。翻譯在裝置端執行且免費,沒有任何東西離開手機,這使它成為應用程式內翻譯的合理預設。代價在於翻譯品質與語言覆蓋是好,而非頂尖,因此高風險的工作或許仍需要雲端服務。
為什麼第一次翻譯會卡住或需要下載?
翻譯在裝置端執行,但語言配對必須先在裝置上。您第一次翻譯某組來源到目標的配對時,系統會下載語言套件,這需要時間與網路連線5。請檢查可用性,並在需要的時刻之前先準備(預先下載)該配對,如此便能顯示「正在準備」的狀態,而非在互動進行到一半時卡住。
為應用程式加入翻譯有哪兩種方式?
透過 SwiftUI 呈現修飾器的系統彈出視窗,或由一個直接建構、用於無 UI 工作的 TranslationSession 所驅動的您自己的 UI4。由於這些介面都是 SwiftUI 修飾器,一個 UIKit 畫面得透過 UIHostingController 寄載一個 SwiftUI 視圖才能取用它們。
Apple 的 Translation 框架能在模擬器中運作嗎?
不行。這個框架無法在 iOS 或 iPadOS 模擬器中執行,因此您得在實機上測試翻譯4。這項限制是硬性的,而非建議性的,它也讓自動化模擬器 UI 測試中的翻譯無法進行。
我要如何讓一個 Foundation Models 功能在任何語言中運作?
把它括起來:把使用者的輸入翻譯成您的邏輯用以推理的語言,在翻譯後的文字上執行 Foundation Models 的工作,再把結果翻譯回去。兩個方向使用兩套 TranslationSession 設定(他們的語言轉成英文,然後英文再轉回去),因為一個工作階段只設定為一組語言配對。兩個層次都在裝置端且免費,於是多語言版本不會付出任何隱私代價或雲端帳單。
我什麼時候不該使用裝置端翻譯?
當您需要最佳品質或最廣的語言覆蓋時(法律、醫療、出版內容);當一個功能必須在首次啟動、無網路的情況下立即運作而您又無法預先下載時;或當您的流程必須在模擬器中執行,或屬於沒有空間容納 SwiftUI 寄載的 UIKit 時。最後這幾項限制是硬性的上限。
-
Apple Developer, “Translation” framework. A first-party framework for on-device, system-provided translation built on Core ML models, performing translation locally without a network call once language assets are installed. ↩
-
Apple Developer, “translationPresentation(isPresented:text:attachmentAnchor:arrowEdge:replacementAction:)” (iOS 17.4+) presents the system’s built-in translation UI over a view; “translationTask(_:action:)” (iOS 18+) runs an async closure that provides a
TranslationSessionfor programmatic translation in your own interface. ↩↩↩ -
Apple Developer,
TranslationSessionandTranslationSession.Request.translate(_:)handles a single string; the batch API takes an array of requests, each carrying aclientIdentifierthat returns on the matching response so results can be reassociated with their inputs independent of order. ↩↩↩ -
The Translation framework’s translation APIs are surfaced through SwiftUI view modifiers (
translationTask,translationPresentation) and have no UIKit entry point; a UIKit screen hosts a SwiftUI view (for example viaUIHostingController) to use them. The framework also requires a physical device and does not function in the iOS Simulator. See the Translation framework documentation and “Translating text within your app”. ↩↩↩↩↩ -
Apple Developer, “Translating text within your app” and
LanguageAvailability. The first translation of a source-to-target language pair downloads the required language assets; the framework exposes language-availability checks and a way to prepare (download) a pair in advance so apps can manage the download moment rather than stall on first use. ↩↩↩↩ -
Author’s related analysis on composing on-device capabilities: Apple Foundation Models: The On-Device LLM Framework, On-Device LLMs with Apple’s Foundation Models, and Writing Tools API adoption. The translate-in, reason, translate-out pattern brackets a monolingual Foundation Models call with Translation to make an on-device feature multilingual without leaving the device. ↩