A CLI da Lingo.dev traduz Xcode String Catalogs (.xcstrings) através de um motor de localização configurado. Os String Catalogs são o formato moderno de localização da Apple, introduzido no Xcode 15, que guarda todos os idiomas num único ficheiro JSON. A CLI altera este ficheiro no local — sem necessidade de diretórios por idioma.
Este guia mostra, de ponta a ponta, como localizar uma app iOS: configurar a CLI, traduzir localmente e automatizar com GitHub Actions para que as traduções sejam publicadas a cada push.
Repositório de demonstração
Faça clone ou fork de lingodotdev/ios-app-localization-example para acompanhar. 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 gerir ficheiros .strings e .stringsdict separados em vários diretórios [locale].lproj/. Os String Catalogs substituem esta abordagem por um único ficheiro Localizable.xcstrings que o Xcode mantém automaticamente.
Quando marca uma string como localizável em SwiftUI ou UIKit, o Xcode deteta-a durante a compilação e adiciona uma entrada ao String Catalog. Cada entrada inclui a string de origem, as respetivas traduções para cada idioma configurado e um campo de comentário opcional que dá contexto aos tradutores.
| Aspeto | .strings legado | String Catalogs .xcstrings |
|---|---|---|
| Número de ficheiros | Um por idioma e por tabela | Um ficheiro, todos os idiomas |
| Formato | Texto de chave-valor | JSON estruturado |
| Suporte de plurais | Ficheiro .stringsdict separado | Regras de plural integradas |
| Integração com o Xcode | Exportação/importação manual | Deteção automática |
| Notas para tradutores | Não suportado | Campo de comentário por entrada |
O tipo de bucket xcode-xcstrings da CLI analisa esta estrutura JSON, traduz cada entrada através do motor de localização e escreve as traduções no mesmo ficheiro — preservando comentários, regras de plural e metadados.
Pré-requisitos#
Criar um motor de localização
Cada execução da CLI envia conteúdo através de um motor de localização — a configuração que determina que modelo LLM, glossário, voz da marca e instruções se aplicam. Crie um no dashboard da Lingo.dev e gere uma chave de API.
Verificar o Node.js
A CLI requer Node.js 18 ou superior:
node -vAtivar a localização no Xcode
No seu projeto Xcode, vá a Project Settings > Info > Localizations e adicione os idiomas de destino. O Xcode cria as entradas do String Catalog para cada idioma que adicionar. Consulte a documentação de localização da Apple para mais detalhes.
Configurar a CLI#
Crie um ficheiro i18n.json na raiz do projeto. O bucket xcode-xcstrings indica à CLI que deve analisar o formato String Catalog e alterar o ficheiro 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 guardam todos os idiomas num único ficheiro, não é necessário um marcador [locale] no padrão de inclusão. A CLI lê as entradas no idioma de origem, traduz-as e escreve todos os idiomas de destino no mesmo ficheiro .xcstrings.
Vários String Catalogs
Se o seu projeto usar vários ficheiros String Catalog (por exemplo, um por target de framework), liste-os todos no array include:
{
"buckets": {
"xcode-xcstrings": {
"include": [
"MyApp/Localizable.xcstrings",
"MyAppWidgets/Localizable.xcstrings"
]
}
}
}Traduzir localmente#
Defina a sua chave de API e execute a CLI:
export LINGO_API_KEY="your-api-key"
npx lingo.dev@latest runA CLI lê o seu String Catalog, identifica as entradas ainda não traduzidas com o lockfile, traduz o delta através do seu motor de localização e escreve os resultados de volta no ficheiro .xcstrings. Abra o ficheiro no Xcode para ver as traduções preenchidas para cada idioma configurado.
Para direcionar um idioma específico durante o desenvolvimento:
npx lingo.dev@latest run --target-locale esNotas para tradutores#
Os String Catalogs suportam um campo de comentário por entrada, que a CLI inclui nos pedidos de tradução. Estes comentários dão contexto ao motor de localização — desambiguam termos, especificam o tom ou descrevem onde uma string aparece na UI.
No Xcode, selecione uma string no editor de String Catalog e adicione um comentário no painel do inspetor. O comentário é guardado no JSON .xcstrings:
{
"sourceLanguage": "en",
"strings": {
"Set": {
"comment": "Refers to a collection of items, not the verb",
"localizations": { }
}
}
}A CLI envia este comentário juntamente com a string, orientando o modelo para a interpretação correta. "Set", sem contexto, pode tornar-se um verbo em muitas línguas — o comentário elimina essa ambiguidade. Consulte Translator Notes para ver mais padrões.
Plurais#
Os String Catalogs tratam formas de plural de forma nativa através das regras de plural CLDR. Quando define uma variação de 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 esta 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 polaco de quatro e o japonês de uma. O motor de localização trata automaticamente estas diferenças.
Automatizar com GitHub Actions#
Adicione um ficheiro de workflow em .github/workflows/translate.yml para traduzir a cada push:
As traduções são enviadas diretamente para main — fricção zero, ideal para equipas pequenas:
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 }}Guarde a sua chave de API como LINGODOTDEV_API_KEY em Settings > Secrets and variables > Actions no seu repositório GitHub.
Verificar antes de fazer deploy#
Use a flag --frozen como gate de deploy para garantir que nenhuma string por traduzir chega à produção. A CLI termina com um estado diferente de zero se houver entradas por traduzir:
npx lingo.dev@latest run --frozenAdicione isto como uma etapa de CI separada antes da compilação:
- name: Verify translations
run: npx lingo.dev@latest run --frozen