Key takeaways
🌁 Adopt .translationPresentation() to display translations
⚙️ Use TranslationSession for deeper integration with your app’s UI
😥 Not a lot of languages are available
Presenters
Louie Livon-Bemel, Senior Engineer, Machine Translation
New Translation.framework
Available on iOS, iPadOS and macOS.
Contents of the video:
the 2 options available
Simple overlay
Flexible translation
Language support
Best practices
Simple overlay
In iOS/iPadOS 17.4 and macOS 14.4 the .translationPresentation modifier was added.
This is the easiest way to show translations:
MyContentView()
.translationPresentation(isPresented: $showsTranslation, text: inputText)This will show a sheet with the translation and a possibility to change target language.
Flexible translation
To translate one or more strings use the new TranslationSession:
let session: TranslationSession
let inputStrings: [String] = ...
let requests: [TranslationSession.Request] = inputString.map { .init(sourceText: $0) }
for response in try? await session.translations(from: requests) {
handle(response: response)
}The TranslationSession should not be created, but the new .translationTask modifier in SwiftUI provides the session for you to use.
The TranslationSession.Configuration parameter not required. Changing the configuration triggers the closure/translation again.
If you want to translate again with the same configuration, call invalidate() on the configuration.
import SwiftUI
import Translation
struct MyView: View {
var sourceText: String
@State private var targetText: String?
@State private var configuration: TranslationSession.Configuration?
var body: some View {
Text(targetText ?? sourceText)
.translationTask(configuration { session in
do {
let response = session.translate(sourceText)
targetText = response.targetText
} catch { /* Handle error */ }
}
}
}Language support)
The translation is done on-device. Downloaded ML models for translate is shared with all apps, including Apple’s Translate.
Arabic
Chinese (Simplified)
Chinese (Traditional)
Dutch
English (UK)
English (US)
French
German
Hindi
Indonesian
Italian
Japanese
Korean
Polish
Portugese (Brazil)
Russian
Spanish (Spain)
Thai
Turkish
Ukranian
Vietnamese
When a model is not downloaded and the Translation API is called, a sheet is presented to let the user download the required models (which continues in background).
It is possible to provide source and target language in the .translationTask modifier and in the TranslationSession.Configuration initializer.
Giving a
nilsource language will let the session attempt to identify languageGiving a
niltarget language will let the session pick a language automatically
Use the language values from LanguageAvailability.supportedLanguages (in the form en_US, zh_CN, fr_FR).
It is recommended to use nil as source language. If you need to identify the language of text use NLLanguageRecognizer:
import NaturalLanguage
func identifyLanguage(of sample: String) -> Locale.Language? {
let recognizer = NLLanguageRecognizer()
recognizer.processString(sample)
guard let language = recognizer.dominantLanguage else { return nil }
return Locale.Language(identifier: language.rawValue)
}Unsupported combinations
The framework does not support every combination of languages.
let availability = LanguageAvailability()
// .supported or .installed
let usToHi = await availability.status(from: englishUS, to: hindi)
let ukToHi = await availability.status(from: englishUK, to: hindi)
// .unsupported
let usToUk = await availability.status(from: englishUS, to: englishUK)
let hiToHi = await availability.status(from: hindi, to: hindi)It is also possible to check with a snippet instead of source language:
let snippet = "The quick brown fox jumped over the lazy dog"
let statusForSnippet = try? await availability.status(for: snippet, to: hindi)Batch translations
There are two possibilities for batch translation.
All at once
public func translations(from batch: [Request]) async throws -> [Response]
This function returns when all has been translated. They keep the order in the arrays.
Streaming
public func translate(batch: [Request]) -> BatchResponse
This function returns like an AsyncSequence. They are not in order.
Make sure to use the clientIdentifier on each Request to find the right translations.
Best practices
Develop with device, not simulator (doesn’t work)
Attach the
.translationPresentationto the content or container - not the buttonAll source texts for a translation should have the same source language
Don’t store instances of `TranslationSession
Use the SF Symbol for translation
Pre-download languages
If you know the languages you will use, you can ask the user for download approval without translating:
TranslationSession.prepareTranslation()

