A CLI da Lingo.dev traduz String Catalogs do Xcode (.xcstrings) por meio de uma engine de localização configurada. String Catalogs são o formato moderno de localização da Apple, introduzido no Xcode 15, que reúne todos os idiomas em um único arquivo JSON. A CLI atualiza esse arquivo no local, sem precisar de diretórios separados por idioma.
Este guia mostra o processo completo de localização de um app iOS: como configurar a CLI, traduzir localmente e automatizar tudo com GitHub Actions para que as traduções acompanhem cada push.
Repositório de demonstração
Faça clone ou fork de lingodotdev/ios-app-localization-example para acompanhar o passo a passo. O repositório inclui um projeto Xcode funcional com String Catalogs, uma configuração da CLI da Lingo.dev e um workflow do GitHub Actions.
Como funcionam os String Catalogs#
Antes do Xcode 15, a localização no iOS exigia gerenciar arquivos separados .strings e .stringsdict em diretórios [locale].lproj/. Os String Catalogs substituem essa estrutura por um único arquivo Localizable.xcstrings, mantido automaticamente pelo Xcode.
Quando você marca uma string como localizável no SwiftUI ou UIKit, o Xcode a detecta durante a build e adiciona uma entrada ao String Catalog. Cada entrada registra a string de origem, suas traduções para cada idioma configurado e um campo opcional de comentário que dá contexto aos tradutores.
| Aspecto | .strings legado | String Catalogs .xcstrings |
|---|---|---|
| Quantidade de arquivos | Um por idioma por tabela | Um arquivo, todos os idiomas |
| Formato | Texto em chave-valor | JSON estruturado |
| Suporte a plural | Arquivo .stringsdict separado | Regras de plural nativas |
| Integração com o Xcode | Exportação/importação manual | Detecção automática |
| Notas para tradutores | Sem suporte | Campo de comentário por entrada |
O tipo de bucket xcode-xcstrings da CLI interpreta essa estrutura JSON, traduz cada entrada por meio da engine de localização e grava as traduções de volta no mesmo arquivo, preservando comentários, regras de plural e metadados.
Pré-requisitos#
Crie uma engine de localização
Cada execução da CLI envia o conteúdo por uma engine de localização — a configuração que define qual modelo de LLM, glossário, voz da marca e instruções serão aplicados. Crie uma no dashboard da Lingo.dev e gere uma chave de API.
Verifique o Node.js
A CLI requer Node.js 18 ou superior:
node -vAtive a localização no Xcode
No seu projeto Xcode, acesse Project Settings > Info > Localizations e adicione os idiomas de destino. O Xcode cria as entradas do String Catalog para cada idioma adicionado. Consulte a documentação de localização da Apple para mais detalhes.
Configure a CLI#
Crie um arquivo i18n.json na raiz do projeto. O bucket xcode-xcstrings informa à CLI que ela deve interpretar o formato de String Catalog e atualizar o arquivo no local:
{
"$schema": "https://lingo.dev/schema/i18n.json",
"version": "1.15",
"locale": {
"source": "en",
"targets": ["es", "fr", "de", "ja"]
},
"buckets": {
"xcode-xcstrings": {
"include": ["MyApp/Localizable.xcstrings"]
}
}
}Como os String Catalogs armazenam todos os idiomas em um único arquivo, não é necessário usar o placeholder [locale] no padrão include. A CLI lê as entradas do idioma de origem, traduz e grava todos os idiomas de destino no mesmo arquivo .xcstrings.
Vários String Catalogs
Se o seu projeto usa vários arquivos de String Catalog (por exemplo, um por target de framework), liste todos eles no array include:
{
"buckets": {
"xcode-xcstrings": {
"include": [
"MyApp/Localizable.xcstrings",
"MyAppWidgets/Localizable.xcstrings"
]
}
}
}Traduza localmente#
Defina sua chave de API e execute a CLI:
export LINGO_API_KEY="your-api-key"
npx lingo.dev@latest runA CLI lê seu String Catalog, identifica as entradas ainda não traduzidas usando o lockfile, traduz apenas o delta por meio da sua engine de localização e grava o resultado de volta no arquivo .xcstrings. Abra o arquivo no Xcode para ver as traduções preenchidas em cada idioma configurado.
Para segmentar um idioma específico durante o desenvolvimento:
npx lingo.dev@latest run --target-locale esNotas para tradutores#
String Catalogs oferecem suporte a um campo de comentário por entrada, que a CLI inclui nas solicitações de tradução. Esses comentários dão contexto à engine de localização — ajudam a desambiguar termos, especificar o tom ou indicar onde a string aparece na interface.
No Xcode, selecione uma string no editor de String Catalog e adicione um comentário no painel do inspetor. O comentário é armazenado no JSON .xcstrings:
{
"sourceLanguage": "en",
"strings": {
"Set": {
"comment": "Refers to a collection of items, not the verb",
"localizations": { }
}
}
}A CLI envia esse comentário junto com a string, orientando o modelo para a interpretação correta. "Set", sem contexto, pode virar um verbo em muitos idiomas — o comentário elimina essa ambiguidade. Veja Translator Notes para conhecer mais padrões.
Plurais#
String Catalogs tratam formas plurais nativamente com regras de plural do CLDR. Quando você define uma variação plural no Xcode, o String Catalog armazena regras para cada categoria de plural (zero, one, two, few, many, other) exigida pelo idioma de destino.
A CLI preserva essa estrutura durante a tradução e gera as categorias de plural corretas para cada idioma de destino. O inglês usa duas categorias (one e other), mas o árabe precisa de seis, o polonês de quatro e o japonês de uma. A engine de localização lida com essas diferenças automaticamente.
Automatize com GitHub Actions#
Adicione um arquivo de workflow em .github/workflows/translate.yml para traduzir a cada push:
As traduções são commitadas direto na main — sem atrito, ideal para times pequenos:
name: Translate
on:
push:
branches: [main]
permissions:
contents: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Lingo.dev
uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}Armazene sua chave de API como LINGODOTDEV_API_KEY em Settings > Secrets and variables > Actions no repositório do GitHub.
Verifique antes do deploy#
Use a flag --frozen como gate de deploy para garantir que nenhuma string sem tradução chegue à produção. A CLI encerra com um status diferente de zero se houver entradas que ainda precisem ser traduzidas:
npx lingo.dev@latest run --frozenAdicione isso como uma etapa separada no CI antes da build:
- name: Verify translations
run: npx lingo.dev@latest run --frozen