One of the new features from Apple is Apple Intelligence (require iPhone 15 pro, iPhone 15 pro Max, iPhone 16 family and iOS18). With it, it’s possible to use the translator for both automatic and manual translations. In this post, we’ll see how to use both approaches.Note that when the app starts, a dialog is displayed informing the user that online services are used for translations.
Manual translation
Let’s start with the code:
import SwiftUI
import Translation
struct ContentView: View {
@State private var originalText = ""
@State private var translatedText = ""
@State private var showingTranslation = false
var body: some View {
VStack {
TextEditor(text: $originalText)
.translationPresentation(
isPresented: $showingTranslation,
text: originalText
) { translatedText in
self.originalText = translatedText
}
Button("Translate") {
showingTranslation = true
}
}
}
}By importing the translation module, we can use translationPresentation just like we would for a sheet (you can check out the post about this topic for more details). When tapping the Translate button, the translation dialog is displayed:

Next, we can choose the target language — in my case, Italian:

Here, you can copy the translation, choose to replace the original text (as I did), or access other available options.

Automatic translation
Now, let’s see how to perform an automatic translation.
Imagine that your application contains a lot of text in English, and you want to translate it in real-time into the language selected on the phone (usually the device’s local language).
In this example, the app starts with the English text “Hello developers” and automatically translates it into Italian.
Note: If, the first time the application starts, one of the required languages is missing, a dialog will appear asking the user to download the missing language data.
Take a look to the code:
import SwiftUI
import Translation
struct ContentView: View {
@State private var sourceText = "Hello developers!"
var sourceLanguage : Locale.Language = Locale.Language(identifier: "en")
var targetLanguage: Locale.Language?
@State private var targetText: String?
@State private var configuration: TranslationSession.Configuration?
var body: some View {
VStack {
Text(targetText ?? sourceText)
.translationTask(configuration) { session in
Task { @MainActor in
do {
let response = try await session.translate(sourceText)
targetText = response.targetText
} catch {
// code to handle error
}
}
}
}.onAppear() {
guard configuration == nil else {
configuration?.invalidate()
return
}
configuration = TranslationSession.Configuration(
source: sourceLanguage,
target: targetLanguage)
}
}
}We define the text to translate, set the initial language (English in this case), and use the device’s local language as the default target.
When the VStack is displayed, the configuration is initialized. Once the configuration is set, the translation task starts on the main thread (Main Actor).
If everything goes well, the original text is replaced with the translated version.
