Genmoji y NSAdaptiveImageGlyph: Emoji en línea en iOS 18+
Genmoji es el nombre de cara al usuario para la función de emoji personalizado de Apple Intelligence: el usuario escribe una descripción, el sistema genera una imagen en línea similar a un emoji, y el resultado aparece en el texto junto a los emoji Unicode. La superficie de cara al desarrollador es NSAdaptiveImageGlyph, una clase de iOS 18+ que representa imágenes en línea adaptativas en texto con atributos1. Genmoji es una fuente de instancias de NSAdaptiveImageGlyph; las apps que manejan texto con atributos necesitan soportar la clase para mostrar Genmoji (y cualquier contenido futuro de glifos de imagen adaptativa que Apple introduzca).
TL;DR
NSAdaptiveImageGlyph(iOS 18+) es un tipo de datos que envuelve una imagen adaptativa más metadatos identificativos. La entrada de Genmoji desde el teclado del sistema llega como instancias deNSAdaptiveImageGlyphincrustadas en texto con atributos2.supportsAdaptiveImageGlyphestá declarada en el protocoloUITextInput;UITextViewse ajusta a él, por lo que la propiedad se puede establecer comotextView.supportsAdaptiveImageGlyph = true. La explicación de Apple es directa: cuando la propiedad esfalse, “el sistema de entrada no permite que la entrada de texto contenga imágenes adaptativas”. Las apps deben optar por incluirlo para que Genmoji se renderice.- Los glifos de imagen adaptativa requieren TextKit 2. Las apps que aún usan TextKit 1 no renderizan
NSAdaptiveImageGlyphcorrectamente. Las apps nuevas dirigidas a iOS 18+ deberían usar TextKit 2 por defecto. NSAttributedStringtransporta glifos de imagen adaptativa mediante el atributoNSAttributedString.Key.adaptiveImageGlyph. El inicializadorNSAttributedString(adaptiveImageGlyph:attributes:)construye una cadena con atributos que contiene un solo glifo3.- La persistencia y el ida y vuelta requieren cuidado. El almacenamiento de texto plano elimina por completo Genmoji; los formatos de texto enriquecido (RTFD, Markdown con extensiones, HTML con datos de imagen incrustados) los preservan.
Qué transporta NSAdaptiveImageGlyph
Un NSAdaptiveImageGlyph es un envoltorio de datos con cuatro propiedades identificativas2:
imageContent: Data. Los datos de la imagen en sí, en el formato declarado porcontentType.contentIdentifier: String. Un identificador único para la instancia del glifo. Se usa para deduplicación y para el almacenamiento en caché interno del sistema.contentDescription: String. Texto alternativo que describe el glifo. Las apps que muestran etiquetas de accesibilidad o que envían glifos a destinatarios que no soportan glifos usan esto.contentType: UTType. Una propiedad de tipo a nivel de clase que expone el formato de imagen que Apple usa para los glifos adaptativos (una variante HEIC). Las apps que serializan revisan esto para impulsar el manejo según el formato.
Los datos suelen ser de decenas de kilobytes para un Genmoji estándar. Múltiples tamaños se codifican en el mismo archivo de imagen usando las funciones de imagen adaptativa de HEIC; el sistema elige el tamaño correcto según el contexto de renderizado.
Habilitar glifos de imagen adaptativa en UITextView
La inclusión es una sola propiedad1:
import UIKit
let textView = UITextView()
textView.supportsAdaptiveImageGlyph = true
// TextKit 2 is required; modern UITextView usage gets it by default
// (see: developer.apple.com/documentation/uikit/using-textkit-2-to-interact-with-text)
Sin supportsAdaptiveImageGlyph = true, el Genmoji escrito por el usuario aparece como un carácter de marcador de posición (el sistema no puede renderizar el glifo). Establecer la propiedad habilita tanto el renderizado como la pestaña “Genmoji” del teclado del sistema, para que el usuario pueda crear Genmoji personalizados dentro de la vista de texto.
TextField y TextEditor nativos de SwiftUI no exponen actualmente un modificador supportsAdaptiveImageGlyph. Las apps de SwiftUI que necesitan renderizado de glifos de imagen adaptativa envuelven UITextView en un UIViewRepresentable y establecen supportsAdaptiveImageGlyph = true en la vista subyacente. Envoltorios comunitarios como GlyphMeThat proporcionan este puente listo para usar.
TextKit 2 es esencial
NSAdaptiveImageGlyph requiere la arquitectura de diseño de TextKit 24. TextKit 1 (el motor de texto heredado que se entregó con el modelo original de NSTextStorage/NSLayoutManager/NSTextContainer) no renderiza correctamente los glifos de imagen adaptativa; el glifo aparece como un marcador de posición genérico o no logra disponerse en absoluto.
Las apps en tres estados:
Apps nuevas en iOS 18+. Usa TextKit 2 por defecto. UITextView inicializado a través de Interface Builder o init(frame:textContainer:) usa TextKit 2 por defecto en iOS 16+4. El código nuevo lo obtiene gratis.
Apps heredadas que aún usan TextKit 1. Se requiere una migración. La migración a TextKit 2 no es trivial para apps que crean subclases de NSLayoutManager, anulan métodos delegados relacionados con el diseño o usan directamente el NSTextStorage más antiguo. La documentación de TextKit 2 de Apple cubre la arquitectura de diseño moderna; para apps con uso simple de UITextView, la migración es en su mayoría automática.
Apps híbridas. Algunas apps incrustan WKWebView para edición HTML junto con UITextView para edición simple. WKWebView maneja los glifos de imagen adaptativa a través de su propia ruta de renderizado (no TextKit), por lo que una app híbrida puede tener una superficie que soporta Genmoji y otra que no. Documenta el comportamiento; los usuarios notan cuando un editor soporta emoji personalizados y el otro los elimina.
Integración con NSAttributedString
Los glifos de imagen adaptativa fluyen a través de cadenas con atributos mediante el atributo NSAttributedString.Key.adaptiveImageGlyph3:
import UIKit
// Construct an attributed string containing a single adaptive image glyph
let glyph: NSAdaptiveImageGlyph = ...
let attrString = NSAttributedString(
adaptiveImageGlyph: glyph,
attributes: [
.font: UIFont.systemFont(ofSize: 17)
]
)
// Concatenate with surrounding text
let composed = NSMutableAttributedString(string: "Look at this ")
composed.append(attrString)
composed.append(NSAttributedString(string: " I just made!"))
El patrón se compone: un glifo dentro de texto dentro de más texto. El sistema maneja el diseño (incluido el dimensionamiento adaptativo del glifo según la fuente del texto circundante) automáticamente.
Para la lectura, iterar el atributo .adaptiveImageGlyph de un NSAttributedString devuelve instancias de NSAdaptiveImageGlyph en las posiciones donde aparecen:
attributedString.enumerateAttribute(
.adaptiveImageGlyph,
in: NSRange(location: 0, length: attributedString.length)
) { value, range, _ in
if let glyph = value as? NSAdaptiveImageGlyph {
// process glyph + range
}
}
Las apps que filtran, transforman o persisten texto usan esta enumeración para encontrar glifos y decidir qué hacer con ellos.
Persistencia y serialización
El almacenamiento de texto plano (un String, un archivo UTF-8) no preserva los glifos de imagen adaptativa. El carácter Unicode de marcador de posición que representa al glifo en texto con atributos se serializa como U+FFFC (reemplazo de objeto) o nada, y los datos reales del glifo se pierden.
Para una persistencia que admita ida y vuelta, las apps necesitan un formato de texto enriquecido5:
RTFD. El formato de texto enriquecido + adjuntos de Apple. Permite el ida y vuelta de glifos de imagen adaptativa. Lo usan Notas, Mail (al enviar contenido enriquecido) y TextEdit. El formato es verboso (un paquete de directorio con adjuntos) pero sin pérdidas.
HTML con imágenes incrustadas. Compatible con la web. Los glifos se serializan como etiquetas <img> con URI de datos codificadas en base64. Cargas útiles más grandes pero funciona en la mayoría de los receptores que admiten texto enriquecido.
Markdown con extensiones. El Markdown estándar no tiene una sintaxis de glifo de imagen adaptativa, pero los dialectos extendidos (CommonMark con soporte de adjuntos, el propio Markdown extendido de Apple) pueden transportarlos. Documenta el requisito de dialecto para cualquier persistencia basada en markdown.
Las apps que envían texto a través de la red (chat, correo electrónico, redes sociales) deben decidir: preservar los glifos de extremo a extremo (solo funciona si tanto el remitente como el receptor son de iOS 18+ y el transporte admite texto enriquecido), eliminar los glifos y sustituirlos por texto de respaldo (contentDescription), o renderizar el glifo como imagen del sistema e incrustar la imagen. La opción correcta depende de la audiencia y la plataforma.
Fallos comunes
Tres modos de fallo se repiten en la adopción de NSAdaptiveImageGlyph:
Olvidar supportsAdaptiveImageGlyph = true. El error más común. La vista de texto renderiza bien los emoji Unicode pero Genmoji aparece como caracteres de marcador de posición. Solución: establece la propiedad en true en cada UITextView (UIKit) o en cualquier conformador de NSTextInputClient como NSTextView (AppKit). Para SwiftUI, no existe un modificador nativo; envuelve un UITextView en UIViewRepresentable (o NSViewRepresentable en macOS) y establece la propiedad en la vista subyacente.
La persistencia en texto plano elimina los glifos. Guardar el contenido de la vista de texto como text (String plano) descarta Genmoji. El usuario escribe un emoji personalizado, lo ve en la vista de texto, guarda el documento, lo reabre; el emoji ha desaparecido. Solución: persiste como attributedText con un formato de texto enriquecido que admita glifos de imagen adaptativa (RTFD, HTML, formato personalizado con un canal lateral de adjuntos).
La transmisión de red elimina glifos silenciosamente. Una app de mensajería que serializa los mensajes salientes como texto plano elimina Genmoji al enviar. El destinatario ve un carácter de marcador de posición o un espacio vacío. Solución: o bien envía contenido enriquecido (y asegúrate de que el destinatario lo soporte) o sustituye el contentDescription para los receptores de texto plano e incluye los datos de la imagen como un adjunto separado.
Qué significa este patrón para las apps de iOS 18+
Tres conclusiones.
-
Establece
supportsAdaptiveImageGlyph = trueen cada entrada de texto. Las apps que aceptan texto introducido por el usuario deberían incluir por defecto los glifos de imagen adaptativa. Esa única propiedad es la diferencia entre que Genmoji se renderice y que Genmoji se rompa. -
Migra a TextKit 2 si aún estás en TextKit 1. TextKit 1 está en modo de mantenimiento. Las nuevas funciones de la era de iOS 26 (glifos de imagen adaptativa, reescritura en línea de Writing Tools, renderizado de texto Liquid Glass) asumen todas TextKit 2. El costo de la migración es real, pero la alternativa es entregar en un motor de texto en desuso.
-
Elige tu formato de persistencia teniendo en cuenta los glifos de imagen adaptativa. RTFD para almacenamiento nativo de iOS; HTML con imágenes incrustadas para almacenamiento compatible con la web; formato binario personalizado con canal lateral de adjuntos para apps de alto rendimiento. El texto plano es el valor predeterminado equivocado para apps en las que los usuarios escribirán Genmoji.
El cluster completo de Apple Ecosystem: Writing Tools para la superficie paralela de texto de Apple Intelligence; Image Playground para generación de imágenes; App Intents 2.0 para la integración de Apple Intelligence en iOS 26; Foundation Models para el LLM en el dispositivo. El centro está en la Apple Ecosystem Series. Para un contexto más amplio sobre iOS con agentes de IA, consulta la iOS Agent Development guide.
FAQ
¿Mi app obtiene Genmoji “gratis” si solo uso UITextView?
No exactamente. El valor predeterminado de UITextView.supportsAdaptiveImageGlyph es false. Las apps deben optar estableciendo la propiedad en true. Una vez habilitada, la pestaña Genmoji del teclado del sistema aparece para el usuario, y los Genmoji pegados se renderizan correctamente. Sin la inclusión, los Genmoji escritos en otro lugar y pegados en la vista de texto aparecen como caracteres de marcador de posición.
¿Necesito tener Apple Intelligence habilitado para probar Genmoji?
Para la creación completa de Genmoji, sí. El flujo de creación de Genmoji de cara al usuario requiere hardware compatible con Apple Intelligence (iPhone 15 Pro y posteriores, Mac con chip de la serie M) con iOS 18+ y Apple Intelligence habilitado. Para pruebas de desarrollo del renderizado de NSAdaptiveImageGlyph, puedes construir instancias de glifos de prueba mediante programación con datos de imagen de muestra y verificar el renderizado de la vista de texto en cualquier dispositivo o simulador con iOS 18+.
¿Qué pasa con un Genmoji cuando se lo envío a alguien que usa iOS 17?
Sin un transporte de texto enriquecido que preserve el glifo, el destinatario ve la contentDescription (texto alternativo) o un carácter de marcador de posición. Los frameworks modernos de mensajería (la app Messages de Apple, las versiones recientes de los clientes de correo) manejan el respaldo automáticamente; los protocolos personalizados necesitan un manejo explícito.
¿Puedo crear instancias de NSAdaptiveImageGlyph mediante programación?
Sí. El inicializador público es init(imageContent: Data), que toma datos de imagen adaptativa HEIC precodificados. contentIdentifier y contentDescription son propiedades de instancia que se leen de la carga útil codificada; contentType es un UTType a nivel de clase que describe el formato que Apple usa para los glifos adaptativos (una variante HEIC) y no es por instancia. Las apps que crean glifos de imagen adaptativa personalizados preparan la carga útil HEIC con el identificador y la descripción por glifo incrustados, luego construyen el glifo a partir de esos datos. La sesión 10220 de la WWDC 2024 (“Bring expression to your app with Genmoji”) cubre el flujo de creación completo.
¿Cómo interactúa esto con Writing Tools?
Writing Tools (cubierto en Writing Tools API) preserva los glifos de imagen adaptativa en sus salidas de reescritura. Un usuario que selecciona texto que contiene Genmoji y le pide a Writing Tools que reescriba obtiene una reescritura que preserva el Genmoji en posiciones semánticamente apropiadas. Las apps que participan en Writing Tools mediante UIWritingToolsCoordinator necesitan transportar correctamente las instancias de NSAdaptiveImageGlyph ida y vuelta a través de su almacenamiento de texto personalizado.
¿Cuál es la diferencia entre NSAdaptiveImageGlyph y NSTextAttachment?
NSTextAttachment es el sistema de adjuntos más antiguo y amplio para contenido en línea no textual (imágenes, archivos, dibujos personalizados) en texto con atributos. NSAdaptiveImageGlyph es la especialización de iOS 18 para imágenes en línea similares a emoji que se adaptan a las características de la fuente circundante. Ambos se adjuntan mediante atributos de cadena con atributos pero usan claves diferentes (.attachment frente a .adaptiveImageGlyph) y rutas de renderizado diferentes (TextKit 1+TextKit 2 frente a solo TextKit 2). El código nuevo dirigido a contenido al estilo Genmoji usa NSAdaptiveImageGlyph.
Referencias
-
Documentación de Apple Developer:
supportsAdaptiveImageGlyph. La propiedad de inclusión declarada en el protocoloUITextInputal que se ajustaUITextView; por lo tanto, la misma propiedad es accesible comotextView.supportsAdaptiveImageGlyph. ↩↩ -
Documentación de Apple Developer:
NSAdaptiveImageGlyph. El tipo de datos que envuelve el contenido de la imagen, el identificador, la descripción y el tipo de contenido. ↩↩ -
Documentación de Apple Developer:
NSAttributedString.Key.adaptiveImageGlyphyNSAttributedString(adaptiveImageGlyph:attributes:). La superficie de integración de cadenas con atributos para glifos de imagen adaptativa. ↩↩ -
Documentación de Apple Developer: TextKit y Using TextKit 2 to interact with text. Los puntos de entrada actuales de TextKit 2; el renderizado de glifos de imagen adaptativa depende de la arquitectura de diseño de TextKit 2. ↩↩
-
Documentación de Apple Developer:
NSAttributedString.DocumentType. Los formatos de texto enriquecido admitidos (RTFD, HTML, etc.) para el ida y vuelta de glifos de imagen adaptativa a través de la persistencia. ↩