Genmoji e NSAdaptiveImageGlyph: emoji inline no iOS 18+
Genmoji é o nome voltado ao usuário do recurso de emoji personalizado da Apple Intelligence: o usuário digita uma descrição, o sistema gera uma imagem inline parecida com emoji, e o resultado aparece no texto ao lado dos emojis Unicode. A superfície voltada ao desenvolvedor é a NSAdaptiveImageGlyph, uma classe do iOS 18+ que representa imagens inline adaptativas em texto atribuído1. Genmoji é uma das fontes de instâncias de NSAdaptiveImageGlyph; aplicativos que lidam com texto atribuído precisam suportar a classe para exibir Genmoji (e qualquer conteúdo futuro de adaptive-image-glyph que a Apple introduzir).
TL;DR
NSAdaptiveImageGlyph(iOS 18+) é um tipo de dados que encapsula uma imagem adaptativa mais metadados de identificação. A entrada de Genmoji vinda do teclado do sistema chega como instâncias deNSAdaptiveImageGlyphembutidas em texto atribuído2.supportsAdaptiveImageGlyphé declarada no protocoloUITextInput;UITextViewestá em conformidade, então a propriedade pode ser definida comotextView.supportsAdaptiveImageGlyph = true. A discussão da Apple é direta: quando a propriedade éfalse, “o sistema de entrada não permite que a entrada de texto contenha imagens adaptativas”. Os aplicativos precisam optar por aderir para que o Genmoji seja renderizado.- Adaptive image glyphs exigem TextKit 2. Aplicativos ainda no TextKit 1 não renderizam
NSAdaptiveImageGlyphcorretamente. Novos aplicativos visando iOS 18+ devem usar TextKit 2 por padrão. NSAttributedStringcarrega adaptive image glyphs através do atributoNSAttributedString.Key.adaptiveImageGlyph. O inicializadorNSAttributedString(adaptiveImageGlyph:attributes:)constrói uma string atribuída contendo um único glyph3.- A persistência e o round-tripping exigem cuidado. O armazenamento em texto puro remove o Genmoji por completo; formatos de texto rico (RTFD, Markdown com extensões, HTML com dados de imagem embutidos) os preservam.
O que NSAdaptiveImageGlyph carrega
Um NSAdaptiveImageGlyph é um wrapper de dados com quatro propriedades de identificação2:
imageContent: Data. Os dados da imagem em si, no formato declarado porcontentType.contentIdentifier: String. Um identificador único para a instância do glyph. Usado para deduplicação e para o cache interno do sistema.contentDescription: String. Texto alternativo descrevendo o glyph. Aplicativos que expõem rótulos de acessibilidade ou que enviam glyphs para destinatários sem suporte a glyphs usam isso.contentType: UTType. Uma propriedade de tipo no nível da classe que expõe o formato de imagem que a Apple usa para adaptive glyphs (uma variante de HEIC). Aplicativos que serializam verificam isso para guiar o tratamento ciente do formato.
Os dados costumam ter dezenas de kilobytes para um Genmoji padrão. Múltiplos tamanhos são codificados no mesmo arquivo de imagem usando os recursos de adaptive-image do HEIC; o sistema escolhe o tamanho certo com base no contexto de renderização.
Habilitando adaptive image glyphs no UITextView
A adesão é uma única propriedade1:
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)
Sem supportsAdaptiveImageGlyph = true, o Genmoji digitado pelo usuário aparece como um caractere de placeholder (o sistema não consegue renderizar o glyph). Definir a propriedade habilita tanto a renderização quanto a aba “Genmoji” no teclado do sistema, para que o usuário possa criar Genmoji personalizado dentro do text view.
TextField e TextEditor nativos do SwiftUI atualmente não expõem um modificador supportsAdaptiveImageGlyph. Aplicativos SwiftUI que precisam de renderização de adaptive image glyph encapsulam um UITextView em um UIViewRepresentable e definem supportsAdaptiveImageGlyph = true na view subjacente. Wrappers da comunidade como GlyphMeThat fornecem essa ponte pronta para uso.
TextKit 2 é estrutural
NSAdaptiveImageGlyph requer a arquitetura de layout do TextKit 24. O TextKit 1 (o motor de texto legado que veio com o modelo original NSTextStorage/NSLayoutManager/NSTextContainer) não renderiza adaptive image glyphs corretamente; o glyph aparece como um placeholder genérico ou falha em ser disposto no layout.
Aplicativos em três estados:
Novos aplicativos no iOS 18+. Por padrão, TextKit 2. UITextView inicializado pelo Interface Builder ou via init(frame:textContainer:) usa TextKit 2 por padrão no iOS 16+4. Código novo já recebe isso de graça.
Aplicativos legados ainda usando TextKit 1. Uma migração é necessária. A migração para TextKit 2 não é trivial para aplicativos que fazem subclasse de NSLayoutManager, sobrescrevem métodos delegate relacionados a layout, ou usam o NSTextStorage antigo diretamente. A documentação do TextKit 2 da Apple cobre a arquitetura de layout moderna; para aplicativos com uso simples de UITextView, a migração é majoritariamente automática.
Aplicativos híbridos. Alguns aplicativos embutem WKWebView para edição em HTML ao lado de UITextView para edição simples. WKWebView lida com adaptive image glyphs por seu próprio caminho de renderização (não pelo TextKit), então um aplicativo híbrido pode ter uma superfície que suporta Genmoji e outra que não. Documente o comportamento; os usuários percebem quando um editor suporta emoji personalizado e o outro o remove.
Integração com NSAttributedString
Adaptive image glyphs fluem através de strings atribuídas via o 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!"))
O padrão se compõe: um glyph dentro de texto dentro de mais texto. O sistema lida com o layout (incluindo o dimensionamento adaptativo do glyph para a fonte do texto ao redor) automaticamente.
Para a leitura, iterar pelo atributo .adaptiveImageGlyph de um NSAttributedString retorna instâncias de NSAdaptiveImageGlyph nas posições onde elas aparecem:
attributedString.enumerateAttribute(
.adaptiveImageGlyph,
in: NSRange(location: 0, length: attributedString.length)
) { value, range, _ in
if let glyph = value as? NSAdaptiveImageGlyph {
// process glyph + range
}
}
Aplicativos que filtram, transformam ou persistem texto usam essa enumeração para encontrar glyphs e decidir o que fazer com eles.
Persistência e serialização
O armazenamento em texto puro (uma String, um arquivo UTF-8) não preserva adaptive image glyphs. O caractere de placeholder Unicode que representa o glyph no texto atribuído é serializado como U+FFFC (object replacement) ou nada, e os dados reais do glyph são perdidos.
Para uma persistência com round-trip, os aplicativos precisam de um formato de texto rico5:
RTFD. O formato de texto rico + anexos da Apple. Faz round-trip de adaptive image glyphs. Usado por Notas, Mail (ao enviar conteúdo rico) e TextEdit. O formato é verboso (um bundle de diretório com anexos), porém sem perdas.
HTML com imagens embutidas. Amigável à web. Glyphs são serializados como tags <img> com data URIs codificados em base64. Payloads maiores, mas funciona com a maioria dos receptores capazes de texto rico.
Markdown com extensões. Markdown padrão não tem uma sintaxe de adaptive-image-glyph, mas dialetos estendidos (CommonMark com suporte a anexos, o próprio Markdown estendido da Apple) podem carregá-los. Documente o requisito de dialeto para qualquer persistência baseada em markdown.
Aplicativos que enviam texto pela rede (chat, e-mail, redes sociais) precisam decidir: preservar glyphs de ponta a ponta (só funciona se tanto o remetente quanto o destinatário estiverem no iOS 18+ e o transporte suportar texto rico), remover glyphs e substituí-los por um texto fallback (contentDescription), ou renderizar o glyph como uma imagem do sistema e embutir a imagem. A escolha certa depende do público e da plataforma.
Falhas comuns
Três modos de falha se repetem na adoção de NSAdaptiveImageGlyph:
Esquecer supportsAdaptiveImageGlyph = true. O bug mais comum. O text view renderiza emoji Unicode normalmente, mas Genmoji aparece como caracteres de placeholder. Correção: defina a propriedade como true em todo UITextView (UIKit) ou em qualquer conformer de NSTextInputClient, como NSTextView (AppKit). Para SwiftUI, não existe modificador nativo; encapsule um UITextView em UIViewRepresentable (ou NSViewRepresentable no macOS) e defina a propriedade na view subjacente.
Persistência em texto puro removendo glyphs. Salvar o conteúdo do text view como text (String puro) descarta o Genmoji. O usuário digita um emoji personalizado, vê no text view, salva o documento, reabre; o emoji desapareceu. Correção: persista como attributedText com um formato de texto rico que suporte adaptive image glyphs (RTFD, HTML, formato customizado com canal lateral de anexo).
Transmissão pela rede descartando glyphs silenciosamente. Um aplicativo de mensagens que serializa as mensagens de saída como texto puro remove o Genmoji no envio. O destinatário vê um caractere de placeholder ou um espaço vazio. Correção: ou envie conteúdo rico (e garanta que o destinatário o suporte) ou substitua pelo contentDescription para destinatários de texto puro e inclua os dados da imagem como um anexo separado.
O que esse padrão significa para aplicativos no iOS 18+
Três conclusões.
-
Defina
supportsAdaptiveImageGlyph = trueem toda entrada de texto. Aplicativos que aceitam texto digitado pelo usuário, por padrão, precisam optar por aderir a adaptive image glyphs. A única propriedade é a diferença entre Genmoji renderizar e Genmoji quebrar. -
Migre para TextKit 2 se você ainda está no TextKit 1. TextKit 1 está em modo de manutenção. Novos recursos da era do iOS 26 (adaptive image glyphs, reescrita inline do Writing Tools, renderização de texto Liquid Glass) todos assumem TextKit 2. O custo da migração é real, mas a alternativa é entregar em um motor de texto descontinuado.
-
Escolha seu formato de persistência tendo adaptive image glyphs em mente. RTFD para armazenamento iOS nativo; HTML com imagens embutidas para armazenamento compatível com web; formato binário customizado com canal lateral de anexo para aplicativos de alto desempenho. Texto puro é o padrão errado para aplicativos onde os usuários vão digitar Genmoji.
O cluster Apple Ecosystem completo: Writing Tools para a superfície de texto paralela da Apple Intelligence; Image Playground para geração de imagens; App Intents 2.0 para a integração com Apple Intelligence no iOS 26; Foundation Models para o LLM on-device. O hub está na Apple Ecosystem Series. Para um contexto mais amplo de iOS com agentes de IA, veja o iOS Agent Development guide.
FAQ
Meu aplicativo recebe Genmoji “de graça” se eu apenas usar UITextView?
Não exatamente. O padrão para UITextView.supportsAdaptiveImageGlyph é false. Os aplicativos precisam optar por aderir definindo a propriedade como true. Uma vez habilitada, a aba Genmoji do teclado do sistema aparece para o usuário, e Genmojis colados são renderizados corretamente. Sem a adesão, Genmoji digitado em outro lugar e colado no text view aparece como caracteres de placeholder.
Preciso ter Apple Intelligence ativada para testar Genmoji?
Para a criação completa de Genmoji, sim. O fluxo de criação de Genmoji voltado ao usuário requer hardware compatível com Apple Intelligence (iPhone 15 Pro e posteriores, Macs da série M) com iOS 18+ e Apple Intelligence ativada. Para testes de desenvolvimento da renderização de NSAdaptiveImageGlyph, você pode construir instâncias de glyph de teste programaticamente com dados de imagem de exemplo e verificar a renderização do text view em qualquer dispositivo iOS 18+ ou simulador.
O que acontece com um Genmoji quando eu o envio para alguém usando iOS 17?
Sem um transporte de texto rico que preserve o glyph, o destinatário vê o contentDescription (texto alternativo) ou um caractere de placeholder. Frameworks de mensagens modernos (o app Mensagens da Apple, versões recentes de clientes de e-mail) lidam com o fallback automaticamente; protocolos customizados precisam de tratamento explícito.
Posso criar instâncias de NSAdaptiveImageGlyph programaticamente?
Sim. O inicializador público é init(imageContent: Data), recebendo dados de adaptive-image HEIC pré-codificados. contentIdentifier e contentDescription são propriedades de instância lidas a partir do payload codificado; contentType é uma UTType no nível da classe que descreve o formato que a Apple usa para adaptive glyphs (uma variante HEIC) e não é por instância. Aplicativos que criam adaptive image glyphs personalizados preparam o payload HEIC com o identificador e a descrição por glyph embutidos, e então constroem o glyph a partir desses dados. A sessão 10220 da WWDC 2024 (“Bring expression to your app with Genmoji”) cobre o fluxo completo de criação.
Como isso interage com Writing Tools?
Writing Tools (coberto em Writing Tools API) preserva adaptive image glyphs nos seus resultados de reescrita. Um usuário que seleciona um texto contendo Genmoji e pede para o Writing Tools reescrever recebe uma reescrita que preserva o Genmoji em posições semanticamente apropriadas. Aplicativos que participam do Writing Tools através do UIWritingToolsCoordinator precisam fazer round-trip das instâncias de NSAdaptiveImageGlyph corretamente em seu armazenamento de texto customizado.
Qual é a diferença entre NSAdaptiveImageGlyph e NSTextAttachment?
NSTextAttachment é o sistema de anexos mais antigo e mais amplo para conteúdo inline não textual (imagens, arquivos, desenhos personalizados) em texto atribuído. NSAdaptiveImageGlyph é a especialização do iOS 18 para imagens inline parecidas com emoji que se adaptam às características da fonte ao redor. Os dois são anexados através de atributos de string atribuída, mas usam chaves diferentes (.attachment vs .adaptiveImageGlyph) e caminhos de renderização diferentes (TextKit 1+TextKit 2 vs apenas TextKit 2). Código novo voltado para conteúdo no estilo Genmoji usa NSAdaptiveImageGlyph.
Referências
-
Documentação do Apple Developer:
supportsAdaptiveImageGlyph. A propriedade de adesão declarada no protocoloUITextInputao qualUITextViewestá em conformidade; a mesma propriedade é, portanto, acessível comotextView.supportsAdaptiveImageGlyph. ↩↩ -
Documentação do Apple Developer:
NSAdaptiveImageGlyph. O tipo de dados que encapsula o conteúdo da imagem, o identificador, a descrição e o tipo de conteúdo. ↩↩ -
Documentação do Apple Developer:
NSAttributedString.Key.adaptiveImageGlypheNSAttributedString(adaptiveImageGlyph:attributes:). A superfície de integração de attributed-string para adaptive image glyphs. ↩↩ -
Documentação do Apple Developer: TextKit e Using TextKit 2 to interact with text. Os pontos de entrada atuais do TextKit 2; a renderização de adaptive image glyph depende da arquitetura de layout do TextKit 2. ↩↩
-
Documentação do Apple Developer:
NSAttributedString.DocumentType. Os formatos de texto rico suportados (RTFD, HTML, etc.) para o round-trip de adaptive image glyphs através da persistência. ↩