← Todos los articulos

El framework Translation de Apple: gratuito, en el dispositivo y más afilado de lo que parece

El framework Translation de Apple traduce texto en el dispositivo, de forma gratuita, sin clave de API y sin ninguna llamada de red una vez que el idioma está instalado1. Está construido sobre modelos de Core ML, viene integrado con el sistema y le da a una app el mismo motor de traducción que usa la app Translate. Para las funciones multilingües que antes implicaban una factura de traducción en la nube y una pregunta sobre privacidad, el costo vuelve a redondearse a cero. Y al igual que con el framework Foundation Models, lo interesante no es el camino feliz; son los detalles que las demos omiten: la descarga del idioma que bloquea tu primera traducción, el simulador que se niega a funcionar sin avisar y la superficie exclusiva de SwiftUI que condiciona cómo lo adoptas.

TL;DR

  • Dos superficies, dos versiones de iOS. translationPresentation muestra el popover de traducción integrado de Apple (iOS 17.4+). TranslationSession, al que se llega mediante el modificador translationTask, hace traducción programática dentro de tu propia interfaz (iOS 18+)2.
  • La traducción programática es async. Dentro del closure de translationTask obtienes una TranslationSession; la llamas para traducir una cadena o un lote3.
  • El procesamiento por lotes es de primera clase. Traduce una lista en una sola petición y mantén cada resultado emparejado con su entrada, en lugar de iterar y esperar uno a uno3.
  • La interfaz de traducción es exclusiva de SwiftUI y no funciona en el simulador de iOS. Ambas cosas son fáciles de descubrir por las malas; diseña y prueba en consecuencia4.
  • Offline implica primero una descarga. La primera traducción de un par de idiomas descarga los paquetes, lo cual es un momento de UX real que tienes que gestionar, no un detalle5.
  • El emparejamiento que conviene conocer: traduce la entrada del usuario con Translation y luego razona sobre ella con Foundation Models, y así una función de agente monolingüe en el dispositivo funciona en cualquier idioma que el dispositivo pueda instalar.

Dos superficies: el popover del sistema y tu propia interfaz

El framework te da dos maneras distintas de traducir, y elegir la correcta es la mayor parte de la decisión.

La opción ligera es translationPresentation, disponible desde iOS 17.4. La adjuntas a una vista, enlazas una bandera isPresented y pasas el texto; cuando la bandera se vuelve verdadera, el sistema despliega su propio popover de traducción sobre tu contenido2:

.translationPresentation(isPresented: $showTranslation, text: selectedText)

No escribes lógica de traducción y no ves el resultado; Apple es dueño de la interfaz y de la interacción. Para «deja que el usuario traduzca este pasaje», esta es la función completa, y recurrir a algo más pesado es trabajo desperdiciado.

La superficie programática es TranslationSession, disponible desde iOS 18, y se llega a ella mediante el modificador translationTask. El modificador ejecuta un closure asíncrono y te entrega una sesión que tú mismo llamas, de modo que el texto traducido vuelve a tu código y lo renderizas a tu manera2:

.translationTask(configuration) { session in
    let response = try await session.translate("Good morning")
    await MainActor.run { translated = response.targetText }
}

La división es limpia. translationPresentation sirve para mostrarle al usuario una traducción en la interfaz de Apple. TranslationSession sirve para llevar el texto traducido a tus datos y a tus vistas. La mayoría de las apps que hacen algo más que un «traduce esto» puntual recurren a la sesión.

Traducción por lotes: traduce la lista, no el bucle

El detalle que separa una función fluida de una a trompicones es el procesamiento por lotes. Si necesitas traducir una lista (mensajes de chat, entradas de un catálogo, un conjunto de etiquetas), no iteres haciendo await en cada traducción por turno. TranslationSession recibe un lote de peticiones y devuelve las respuestas, cada una emparejada con su petición, en una sola pasada3:

.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
    }
}

El clientIdentifier es la parte que importa: vuelve en la respuesta para que puedas emparejar cada traducción con la fila a la que pertenece sin depender del orden. El procesamiento por lotes también permite que el framework programe el trabajo de forma eficiente en lugar de pagar el sobrecosto de llamada por llamada a lo largo de un bucle. Para cualquier cosa que vaya más allá de una sola cadena, usa lotes.

La realidad offline que nadie captura en pantalla

Aquí está el detalle que convierte una demo limpia en un ticket de soporte. La traducción se ejecuta en el dispositivo, pero el idioma tiene que estar primero en el dispositivo. La primera vez que tu app traduce un par origen-destino determinado, el sistema descarga los paquetes de idioma, y esa descarga lleva tiempo y requiere conexión de red5. Si lanzas una traducción y renderizas el resultado sin gestionar la descarga, tu función parecerá colgarse en el primer uso con cada idioma nuevo.

Gestiónalo de forma deliberada. El framework te permite comprobar la disponibilidad de un idioma y preparar (descargar) un par antes del momento en que lo necesites, para que puedas mostrar un estado de «preparando traducción» o descargarlo por adelantado en un momento más tranquilo en lugar de quedarte trabado a mitad de la interacción5. El modelo mental: trata la primera traducción de un par de idiomas como una descarga de recurso única, porque eso es exactamente lo que es. Planifica la UX contando con que la descarga existe, y el beneficio de ser offline y gratuito da resultado; ignórala, y el beneficio queda oculto tras un cuelgue.

Dos hechos más que te cuestan una tarde si los aprendes tarde. Las superficies de la interfaz de traducción son modificadores de SwiftUI, así que una pantalla de UIKit aloja una vista de SwiftUI (mediante UIHostingController) para alcanzarlas, aunque una TranslationSession también se puede construir directamente para trabajo sin interfaz4. Y el framework no funciona en el simulador de iOS ni de iPadOS; la traducción se prueba en un dispositivo real4. Ninguna de las dos cosas está documentada a gritos, y con ambas es fácil chocar de frente.

Emparejar la traducción con Foundation Models

La síntesis que vale la pena llevarse conecta este framework con el resto del stack en el dispositivo. La mayor parte del trabajo de lenguaje en el dispositivo asume que la entrada está en un idioma que tu lógica y el modelo del sistema manejan bien. Los usuarios reales no cooperan. El framework Translation cierra esa brecha: traduce la entrada del usuario al idioma en el que tu función razona, ejecuta el trabajo de Foundation Models sobre el texto traducido y luego vuelve a traducir el resultado.

La forma es un paréntesis: traduce hacia dentro, razona, traduce hacia fuera.

// 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

Una función de triaje de soporte, un resumidor de notas, un extractor de intención: cada una puede escribirse una vez, de forma monolingüe, y hacerse funcionar en cualquier idioma que el dispositivo pueda instalar, encerrando la llamada a Foundation Models entre dos pasos de Translation. Las dos direcciones usan dos configuraciones de sesión (de su idioma a inglés, y luego de inglés de vuelta), ya que una sesión se configura para un solo par de idiomas. Ambas capas están en el dispositivo, ambas son gratuitas y nada sale del teléfono, de modo que la versión multilingüe no cuesta ni privacidad ni factura en la nube que la versión monolingüe no costara ya. Esa composición (traduce hacia dentro, razona, traduce hacia fuera) es el patrón que hace que una pequeña función en el dispositivo sea genuinamente global, y solo es posible porque ambas mitades se ejecutan localmente de forma gratuita.

Cuándo no usarlo

La traducción en el dispositivo es gratuita y privada, lo que la convierte en el valor por defecto correcto para traducir dentro de una app. Es la herramienta equivocada en unos pocos casos honestos.

  • Necesitas la mejor calidad de traducción posible o la cobertura de idiomas más amplia. Los modelos en el dispositivo son buenos, no los mejores disponibles, y el conjunto de idiomas instalables es finito. Para traducción de alto riesgo (legal, médica, contenido publicado), un servicio de traducción en la nube dedicado sigue ganando en calidad y amplitud.
  • No puedes tolerar la descarga del primer uso. Para una función que debe funcionar al instante en el primer lanzamiento sin red, el requisito de descarga puede descalificar por sí solo a la traducción en el dispositivo, a menos que la descargues por adelantado durante el onboarding.
  • Tu app es de UIKit sin espacio para alojar SwiftUI, o tu flujo debe ejecutarse en el simulador (una prueba de UI automatizada, por ejemplo). Las restricciones de ser exclusivo de SwiftUI y no funcionar en el simulador son límites firmes, no consejos.

El framework es una de las victorias más silenciosas del conjunto de herramientas en el dispositivo: un motor de traducción genuinamente gratuito y privado que la mayoría de las apps podría adoptar en una tarde. La habilidad es la misma que recompensa el resto de este stack. Sabe qué superficie encaja (el popover del sistema o tu propia sesión), usa lotes cuando tengas una lista y diseña contando con la descarga en lugar de fingir que no está ahí. Haz eso, y la traducción deja de ser una dependencia de la nube y se convierte en una capacidad local que compones con todo lo demás que el dispositivo hace de forma gratuita.

Preguntas frecuentes

¿El framework Translation de Apple es gratuito y en el dispositivo?

Sí. La traducción se ejecuta en el dispositivo y es gratuita, sin que nada salga del teléfono, lo que la convierte en el valor por defecto correcto para traducir dentro de una app. La contrapartida es que la calidad de la traducción y la cobertura de idiomas son buenas más que de primer nivel, así que el trabajo de alto riesgo todavía puede preferir un servicio en la nube.

¿Por qué la primera traducción se cuelga o necesita una descarga?

La traducción se ejecuta en el dispositivo, pero el par de idiomas tiene que estar primero en el dispositivo. La primera vez que traduces un par origen-destino determinado, el sistema descarga los paquetes de idioma, lo que requiere tiempo y conexión de red5. Comprueba la disponibilidad y prepara (descarga por adelantado) el par antes del momento en que lo necesites para poder mostrar un estado de «preparando» en lugar de quedarte trabado a mitad de la interacción.

¿Cuáles son las dos formas de añadir traducción a una app?

El popover del sistema mediante un modificador de presentación de SwiftUI, o tu propia interfaz impulsada por una TranslationSession construida directamente para trabajo sin interfaz4. Como las superficies son modificadores de SwiftUI, una pantalla de UIKit las alcanza alojando una vista de SwiftUI mediante UIHostingController.

¿El framework Translation de Apple funciona en el simulador?

No. El framework no se ejecuta en el simulador de iOS ni de iPadOS, así que la traducción se prueba en un dispositivo real4. Esta restricción es un límite firme, no un consejo, y también descarta la traducción dentro de pruebas de UI automatizadas en el simulador.

¿Cómo hago que una función de Foundation Models funcione en cualquier idioma?

Enciérrala entre paréntesis: traduce la entrada del usuario al idioma en el que tu lógica razona, ejecuta el trabajo de Foundation Models sobre el texto traducido y luego vuelve a traducir el resultado. Las dos direcciones usan dos configuraciones de TranslationSession (de su idioma a inglés, y luego de inglés de vuelta), ya que una sesión se configura para un solo par de idiomas. Ambas capas están en el dispositivo y son gratuitas, de modo que la versión multilingüe no cuesta ni privacidad ni factura en la nube.

¿Cuándo no debería usar la traducción en el dispositivo?

Cuando necesitas la mejor calidad posible o la cobertura de idiomas más amplia (legal, médica, contenido publicado), cuando una función debe funcionar al instante en el primer lanzamiento sin red y no puedes descargarla por adelantado, o cuando tu flujo debe ejecutarse en el simulador o es de UIKit sin espacio para alojar SwiftUI. Esas últimas restricciones son límites firmes.



  1. Apple Developer, framework «Translation». Un framework de primera parte para traducción en el dispositivo provista por el sistema, construido sobre modelos de Core ML, que realiza la traducción localmente sin llamada de red una vez que los recursos de idioma están instalados. 

  2. Apple Developer, “translationPresentation(isPresented:text:attachmentAnchor:arrowEdge:replacementAction:)” (iOS 17.4+) presenta la interfaz de traducción integrada del sistema sobre una vista; “translationTask(_:action:)” (iOS 18+) ejecuta un closure asíncrono que provee una TranslationSession para traducción programática dentro de tu propia interfaz. 

  3. Apple Developer, TranslationSession y TranslationSession.Request. translate(_:) maneja una sola cadena; la API por lotes recibe un arreglo de peticiones, cada una con un clientIdentifier que vuelve en la respuesta correspondiente para que los resultados puedan reasociarse con sus entradas independientemente del orden. 

  4. Las APIs de traducción del framework Translation se exponen mediante modificadores de vista de SwiftUI (translationTask, translationPresentation) y no tienen punto de entrada de UIKit; una pantalla de UIKit aloja una vista de SwiftUI (por ejemplo, mediante UIHostingController) para usarlas. El framework también requiere un dispositivo físico y no funciona en el simulador de iOS. Consulta la documentación del framework Translation y “Translating text within your app”

  5. Apple Developer, “Translating text within your app” y LanguageAvailability. La primera traducción de un par de idiomas origen-destino descarga los recursos de idioma necesarios; el framework expone comprobaciones de disponibilidad de idiomas y una manera de preparar (descargar) un par por adelantado para que las apps puedan gestionar el momento de la descarga en lugar de quedarse trabadas en el primer uso. 

  6. Análisis relacionado del autor sobre cómo componer capacidades en el dispositivo: Apple Foundation Models: el framework de LLM en el dispositivo, LLMs en el dispositivo con Foundation Models de Apple y Adopción de la API Writing Tools. El patrón de traducir hacia dentro, razonar y traducir hacia fuera encierra una llamada monolingüe a Foundation Models entre dos pasos de Translation para hacer multilingüe una función en el dispositivo sin que nada salga del dispositivo. 

Artículos relacionados

Image Playground API: hoja de SwiftUI, creador de imágenes programático y control de estilo

Image Playground ofrece a las apps dos caminos: el modificador imagePlaygroundSheet de SwiftUI y la API programática Ima…

11 min de lectura

Genmoji y NSAdaptiveImageGlyph: Emoji en línea en iOS 18+

Genmoji se entrega como NSAdaptiveImageGlyph en texto con atributos. Las apps que usan UITextView con TextKit 2 habilita…

10 min de lectura

The Robots Are Taking Exams in My Search Console

First-party GSC data: 91% of 3.8M impressions fail a human-query filter. Exam questions, pasted errors, and agent sweeps…

10 min de lectura