Le framework Translation d'Apple : gratuit, sur l'appareil, et plus fin qu'il n'y paraît
Le framework Translation d’Apple traduit du texte directement sur l’appareil, gratuitement, sans clé API et sans le moindre appel réseau une fois la langue installée1. Bâti sur des modèles Core ML et livré avec le système, il donne à votre application le moteur de traduction dont se sert l’app Traduire. Pour des fonctionnalités multilingues qui impliquaient jusqu’ici une facture de traduction dans le cloud et une question de confidentialité, le coût retombe une fois de plus à zéro. Et comme pour le framework Foundation Models6, l’intérêt ne réside pas dans le chemin balisé : il est dans les angles morts que les démos évitent — le téléchargement de langue qui bloque votre première traduction, le simulateur qui refuse silencieusement de fonctionner, et une surface exclusivement SwiftUI qui conditionne la façon dont vous l’adoptez.
En bref
- Deux surfaces, deux versions d’iOS.
translationPresentationaffiche la fenêtre contextuelle de traduction intégrée d’Apple (iOS 17.4+).TranslationSession, accessible via le modificateurtranslationTask, assure la traduction programmatique dans votre propre interface (iOS 18+)2. - La traduction programmatique est
async. À l’intérieur de la closuretranslationTask, vous récupérez uneTranslationSession; appelez-la pour traduire une chaîne ou un lot entier3. - Le traitement par lots est une fonctionnalité à part entière. Traduisez une liste en une seule requête et gardez chaque résultat associé à son entrée, plutôt que de boucler en attendant chaque traduction l’une après l’autre3.
- L’interface de traduction est réservée à SwiftUI, et elle ne fonctionne pas dans le simulateur iOS. Ces deux points se découvrent facilement à la dure ; concevez et testez en conséquence4.
- Hors ligne suppose un téléchargement préalable. La première traduction pour une paire de langues télécharge des paquets : un vrai moment d’UX à prendre en charge, pas un détail5.
- L’association à retenir : traduisez la saisie de l’utilisateur avec Translation, raisonnez ensuite dessus avec Foundation Models, et une fonctionnalité d’agent monolingue sur l’appareil se met à fonctionner dans toutes les langues que l’appareil peut installer.
Deux surfaces : la fenêtre contextuelle du système et votre propre interface
Le framework propose deux façons distinctes de traduire, et choisir la bonne constitue l’essentiel de la décision.
L’approche légère, c’est translationPresentation, disponible depuis iOS 17.4. Vous l’attachez à une vue, vous liez un indicateur isPresented et vous passez le texte ; quand l’indicateur bascule à true, le système fait glisser sa propre fenêtre de traduction par-dessus votre contenu2 :
.translationPresentation(isPresented: $showTranslation, text: selectedText)
Vous n’écrivez aucune logique de traduction et vous ne voyez pas le résultat : Apple garde la main sur l’interface et l’interaction. Pour un « laissez l’utilisateur traduire ce passage », c’est là toute la fonctionnalité, et sortir l’artillerie lourde revient à travailler pour rien.
La surface programmatique, c’est TranslationSession, disponible depuis iOS 18, à laquelle vous accédez par le modificateur translationTask. Ce modificateur exécute une closure asynchrone et vous remet une session que vous appelez vous-même, si bien que le texte traduit revient dans votre code et que vous l’affichez à votre façon2 :
.translationTask(configuration) { session in
let response = try await session.translate("Good morning")
await MainActor.run { translated = response.targetText }
}
La séparation est nette. translationPresentation sert à montrer une traduction à l’utilisateur dans l’interface d’Apple. TranslationSession sert à faire entrer du texte traduit dans vos données et dans vos vues. La plupart des applications qui vont au-delà d’un « traduire ceci » ponctuel se tournent vers la session.
Traduction par lots : traduire la liste, pas la boucle
Ce qui sépare une fonctionnalité fluide d’une fonctionnalité poussive, c’est le traitement par lots. Si vous devez traduire une liste (messages de discussion, entrées de catalogue, un ensemble de libellés), ne bouclez pas en faisant await sur chaque traduction à tour de rôle. TranslationSession accepte un lot de requêtes et renvoie les réponses, chacune associée à sa requête, en une seule passe3 :
.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
}
}
Le clientIdentifier est l’élément décisif : il revient sur la réponse, ce qui vous permet d’associer chaque traduction à la ligne à laquelle elle appartient sans dépendre de l’ordre. Le traitement par lots permet par ailleurs au framework de planifier le travail efficacement, au lieu de payer le surcoût d’un appel à chaque itération. Dès qu’il y a plus d’une chaîne à traiter, groupez.
La réalité du hors-ligne que personne ne capture en image
Voici l’angle mort qui transforme une démo impeccable en ticket de support. La traduction s’exécute sur l’appareil, mais la langue doit d’abord s’y trouver. La première fois que votre application traduit une paire source-vers-cible donnée, le système télécharge les paquets linguistiques, et ce téléchargement demande du temps et une connexion réseau5. Si vous lancez une traduction et affichez le résultat sans rien prévoir pour le téléchargement, votre fonctionnalité semble se figer à la première utilisation, pour chaque nouvelle langue.
Prenez-le en charge délibérément. Le framework vous permet de vérifier la disponibilité d’une langue et de préparer (télécharger) une paire en amont du moment où vous en aurez besoin ; vous pouvez ainsi afficher un état « préparation de la traduction » ou lancer le téléchargement pendant un moment plus calme, au lieu de bloquer en pleine interaction5. Le modèle mental : traitez la première traduction d’une paire de langues comme le téléchargement ponctuel d’une ressource, parce que c’est exactement ce dont il s’agit. Concevez l’UX en tenant compte de l’existence de ce téléchargement, et le bénéfice « gratuit et hors ligne » se concrétise ; ignorez-le, et ce bénéfice disparaît derrière un blocage.
Deux autres faits qui coûtent un après-midi si on les apprend trop tard. Les surfaces d’interface de traduction sont des modificateurs SwiftUI : un écran UIKit doit donc héberger une vue SwiftUI (via UIHostingController) pour y accéder, même si une TranslationSession peut aussi être construite directement pour un travail sans interface4. Et le framework ne fonctionne pas dans le simulateur iOS ou iPadOS : la traduction se teste sur un appareil réel4. Ni l’un ni l’autre n’est documenté avec insistance, et on se heurte facilement aux deux.
Associer Translation à Foundation Models
La synthèse à retenir relie ce framework au reste de la pile sur l’appareil. La plupart des traitements linguistiques locaux partent du principe que l’entrée est rédigée dans une langue que votre logique et le modèle système maîtrisent bien. Les vrais utilisateurs, eux, ne coopèrent pas. Le framework Translation comble cet écart : traduisez la saisie de l’utilisateur vers la langue dans laquelle votre fonctionnalité raisonne, exécutez le traitement Foundation Models sur le texte traduit, puis retraduisez le résultat.
La forme est celle d’un encadrement : traduire à l’entrée, raisonner, traduire à la sortie.
// 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
Un tri de demandes d’assistance, un résumé de notes, un extracteur d’intention : chacun s’écrit une seule fois, dans une seule langue, et se met à fonctionner dans toutes les langues que l’appareil peut installer, dès lors que l’appel à Foundation Models est encadré par Translation. Les deux sens mobilisent deux configurations de session (leur langue vers l’anglais, puis l’anglais en retour), puisqu’une session est configurée pour une seule paire de langues. Les deux couches s’exécutent sur l’appareil, toutes deux sont gratuites, et rien ne quitte le téléphone : la version multilingue ne coûte donc pas plus en confidentialité ni en facture cloud que la version monolingue. Cette composition — traduire à l’entrée, raisonner, traduire à la sortie — est le motif qui rend une petite fonctionnalité locale véritablement mondiale, et elle n’est possible que parce que les deux moitiés tournent en local, gratuitement.
Quand ne pas l’utiliser
La traduction sur l’appareil est gratuite et privée, ce qui en fait le choix par défaut pour traduire au sein d’une application. C’est le mauvais outil dans quelques cas qu’il faut nommer honnêtement.
- Vous visez la meilleure qualité de traduction possible ou la couverture linguistique la plus large. Les modèles embarqués sont bons, pas les meilleurs du marché, et l’ensemble des langues installables est fini. Pour une traduction à fort enjeu (juridique, médical, contenu publié), un service de traduction cloud dédié conserve l’avantage en qualité comme en étendue.
- Vous ne pouvez pas tolérer le téléchargement à la première utilisation. Pour une fonctionnalité qui doit marcher instantanément au premier lancement et sans réseau, cette exigence de téléchargement peut à elle seule disqualifier la traduction locale, à moins de télécharger en amont pendant l’accueil initial.
- Votre application est en UIKit sans place pour héberger du SwiftUI, ou votre parcours doit s’exécuter dans le simulateur (un test d’interface automatisé, par exemple). Les contraintes « SwiftUI uniquement » et « pas de simulateur » sont fermes, pas indicatives.
Ce framework est l’une des victoires les plus discrètes de la boîte à outils embarquée : un moteur de traduction réellement gratuit et privé, que la plupart des applications pourraient adopter en un après-midi. Le savoir-faire requis est celui que récompense tout le reste de cette pile. Sachez quelle surface convient (la fenêtre du système ou votre propre session), groupez dès que vous avez une liste, et concevez pour le téléchargement au lieu de faire comme s’il n’existait pas. Faites cela, et la traduction cesse d’être une dépendance cloud pour devenir une capacité locale que vous composez avec tout ce que l’appareil sait faire gratuitement.
FAQ
Le framework Translation d’Apple est-il gratuit et exécuté sur l’appareil ?
Oui. La traduction s’exécute sur l’appareil et elle est gratuite, sans que rien ne quitte le téléphone, ce qui en fait le choix par défaut pour traduire au sein d’une application. La contrepartie : la qualité de traduction et la couverture linguistique sont bonnes sans être au meilleur niveau, si bien qu’un travail à fort enjeu peut encore justifier un service cloud.
Pourquoi la première traduction se fige-t-elle ou réclame-t-elle un téléchargement ?
La traduction s’exécute sur l’appareil, mais la paire de langues doit d’abord y être présente. La première fois que vous traduisez une paire source-vers-cible donnée, le système télécharge les paquets linguistiques, ce qui demande du temps et une connexion réseau5. Vérifiez la disponibilité et préparez (téléchargez à l’avance) la paire en amont du moment où vous en aurez besoin, afin d’afficher un état « préparation » plutôt que de bloquer en pleine interaction.
Quelles sont les deux façons d’ajouter la traduction à une application ?
La fenêtre du système via un modificateur de présentation SwiftUI, ou votre propre interface pilotée par une TranslationSession construite directement pour un travail sans interface4. Comme ces surfaces sont des modificateurs SwiftUI, un écran UIKit y accède en hébergeant une vue SwiftUI par l’intermédiaire d’UIHostingController.
Le framework Translation d’Apple fonctionne-t-il dans le simulateur ?
Non. Le framework ne fonctionne pas dans le simulateur iOS ou iPadOS : la traduction se teste sur un appareil réel4. Cette contrainte est ferme, pas indicative, et elle exclut aussi la traduction au sein de tests d’interface automatisés dans le simulateur.
Comment faire fonctionner une fonctionnalité Foundation Models dans n’importe quelle langue ?
Encadrez-la : traduisez la saisie de l’utilisateur vers la langue dans laquelle votre logique raisonne, exécutez le traitement Foundation Models sur le texte traduit, puis retraduisez le résultat. Les deux sens mobilisent deux configurations de TranslationSession (leur langue vers l’anglais, puis l’anglais en retour), puisqu’une session est configurée pour une seule paire de langues. Les deux couches s’exécutent sur l’appareil et sont gratuites : la version multilingue ne coûte donc rien de plus, ni en confidentialité ni en facture cloud.
Dans quels cas éviter la traduction sur l’appareil ?
Quand vous avez besoin de la meilleure qualité possible ou de la couverture linguistique la plus large (juridique, médical, contenu publié), quand une fonctionnalité doit marcher instantanément au premier lancement sans réseau et que vous ne pouvez pas télécharger en amont, ou quand votre parcours doit s’exécuter dans le simulateur ou repose sur UIKit sans place pour héberger du SwiftUI. Ces dernières contraintes sont des limites fermes.
-
Apple Developer, framework « Translation ». Un framework signé Apple pour la traduction locale fournie par le système, bâti sur des modèles Core ML, qui effectue la traduction en local sans appel réseau une fois les ressources linguistiques installées. ↩
-
Apple Developer, “translationPresentation(isPresented:text:attachmentAnchor:arrowEdge:replacementAction:)” (iOS 17.4+) présente l’interface de traduction intégrée du système par-dessus une vue ; “translationTask(_:action:)” (iOS 18+) exécute une closure asynchrone qui fournit une
TranslationSessionpour la traduction programmatique dans votre propre interface. ↩↩↩ -
Apple Developer,
TranslationSessionetTranslationSession.Request.translate(_:)traite une seule chaîne ; l’API par lots accepte un tableau de requêtes, chacune portant unclientIdentifierqui revient sur la réponse correspondante, de sorte que les résultats peuvent être réassociés à leurs entrées indépendamment de l’ordre. ↩↩↩ -
Les surfaces de traduction du framework Translation sont exposées par des modificateurs de vue SwiftUI (
translationTask,translationPresentation) et n’ont aucun point d’entrée UIKit ; un écran UIKit héberge une vue SwiftUI (par exemple viaUIHostingController) pour les utiliser. Le framework exige en outre un appareil physique et ne fonctionne pas dans le simulateur iOS. Voir la documentation du framework Translation et “Translating text within your app”. ↩↩↩↩↩ -
Apple Developer, “Translating text within your app” et
LanguageAvailability. La première traduction d’une paire de langues source-vers-cible télécharge les ressources linguistiques nécessaires ; le framework expose des vérifications de disponibilité des langues ainsi qu’un moyen de préparer (télécharger) une paire à l’avance, afin que les applications puissent gérer ce moment de téléchargement plutôt que de bloquer à la première utilisation. ↩↩↩↩ -
Analyse connexe de l’auteur sur la composition des capacités locales : Apple Foundation Models : le framework LLM sur l’appareil, Des LLM sur l’appareil avec les Foundation Models d’Apple et L’adoption de l’API Writing Tools. Le motif « traduire à l’entrée, raisonner, traduire à la sortie » encadre un appel monolingue à Foundation Models avec Translation pour rendre une fonctionnalité locale multilingue sans que rien ne quitte l’appareil. ↩