Globalization (globalização, também internacionalização, i18n) — o processo de preparar um aplicativo móvel para funcionar com vários idiomas e formatos regionais sem alterar o código-fonte. Inclui a extração de recursos de string do código, suporte a diferentes formatos de data, número e moeda, consideração da direção do texto (LTR/RTL) e adaptação do layout para diferentes idiomas. No iOS são usados NSLocalizedString e Localizable.strings, no Android — strings.xml em diretórios values-{lang}. Mais informações — em documentação da Apple sobre internacionalização.
Principais pontos
Globalization (abreviado como i18n — 18 letras entre "i" e "n") é a preparação arquitetural de um aplicativo para funcionar com qualquer idioma e região. A regra chave do i18n: nenhuma string de texto deve estar codificada (hardcoded) no código-fonte. Em vez disso, as strings são extraídas para arquivos de recursos, e o código as acessa por chaves. Ao adicionar um novo idioma, basta adicionar um arquivo de tradução — o código permanece inalterado. Isso diferencia i18n da localização (l10n), onde as próprias strings são traduzidas.
Argumento de negócio — a globalização expande o mercado. De acordo com a Common Sense Advisory (2023), mais de 70% dos usuários preferem comprar em aplicativos em seu idioma nativo. A localização para 10 idiomas aumenta o público potencial em 80%. Sem i18n, cada expansão para um novo idioma requer alterações no código, retardando a entrada no mercado e aumentando os custos em 5 a 10 vezes. Uma arquitetura i18n adequada permite suportar mais de 40 idiomas com custos mínimos.
Componentes do i18n incluem: externalização de strings, pluralização (para 1/2/5+), formatação de datas e números (DateFormatter/SimpleDateFormat), suporte a idiomas RTL (Right-to-Left), ordenação por regras de locale (Collator), símbolos regionais (separadores de milhares, decimais). Na IT Sectr, implementamos i18n na fase de arquitetura, não depois — isso economiza até 60% do tempo na localização subsequente.
NSLocalizedString é a macro principal do Swift para trabalhar com traduções. Formato: NSLocalizedString("key", comment: "descrição para o tradutor"). A macro substitui automaticamente a string de Localizable.strings para a localidade atual do dispositivo (NSLocale.preferredLanguages). Se nenhuma tradução for encontrada para a chave, a própria chave ou o valor no idioma de desenvolvimento (geralmente en) é retornado. A Apple recomenda usar chaves significativas em vez de strings em inglês como chaves.
// Localizable.strings (en)
// "welcome_title" = "Welcome!";
// Localizable.strings (ru)
// "welcome_title" = "Bem-vindo!";
// Código Swift — unificado para todos os idiomas
titleLabel.text = NSLocalizedString(
"welcome_title",
comment: "Título da tela de boas-vindas"
)
// Plurais via Localizable.stringsdict
//
// <dict>
// <key>items_count</key>
// <dict>
// <key>NSStringLocalizedFormatKey</key>
// <string>%#@items@</string>
// <key>items</key>
// <dict>
// <key>one</key>
// <string>%d produto</string>
// <key>few</key>
// <string>%d produtos</string>
// <key>many</key>
// <string>%d produtos</string>
// </dict>
// </dict>
// </dict>
// Uso de plurais
let items = 5
let label = String.localizedStringWithFormat(
NSLocalizedString("items_count", comment: ""), items
)
XLIFF — formato de intercâmbio de traduções entre desenvolvedores e tradutores. O Xcode exporta um arquivo XLIFF (Editor → Export for Localization) contendo todas as strings para tradução. O tradutor trabalha com XLIFF em ferramentas CAT (Trados, memoQ, Smartcat). Após a tradução, o XLIFF é importado de volta para o Xcode (Editor → Import Localizations). O XLIFF atualiza automaticamente todos os diretórios .lproj. Este é o fluxo de trabalho padrão de localização para aplicativos iOS em produção.
SwiftUI trabalha com NSLocalizedString através do inicializador Text. O texto no SwiftUI é automaticamente internacionalizado: Text("welcome_title") procura a tradução no Localizable.strings assim como NSLocalizedString. Para plurais, use Text("%d items", count: items). O SwiftUI suporta formatação de data através de Text(date, style: .date) — ele usa automaticamente Locale.current. A Apple recomenda SwiftUI para novos projetos, pois a internacionalização é mais transparente.
Android i18n é construído no sistema de recursos. As strings são colocadas em res/values/strings.xml para o idioma padrão (geralmente inglês). Para cada idioma, é criado um diretório separado: res/values-ru/strings.xml (russo), res/values-de/strings.xml (alemão), res/values-fr/strings.xml (francês). O Android seleciona automaticamente as strings com base no idioma do sistema do dispositivo (Locale.getDefault()). Se uma localidade exata não for encontrada, a base (values/strings.xml) é usada.
// res/values/strings.xml (inglês, padrão)
<resources>
<string name="welcome_title">Welcome!</string>
<string name="items_count">%d item(s)</string>
</resources>
// res/values-ru/strings.xml (russo)
<resources>
<string name="welcome_title">Bem-vindo!</string>
<plurals name="items_count">
<item quantity="one">%d item</item>
<item quantity="few">%d itens</item>
<item quantity="many">%d itens</item>
</plurals>
</resources>
// Código Kotlin
textView.text = getString(R.string.welcome_title)
// Plurais
val items = 5
textView.text = resources.getQuantityString(
R.plurals.items_count, items, items
)
// Suporte RTL no código
textView.textDirection = View.TEXT_DIRECTION_LOCALE
// Manifest: supportsRtl="true"
RTL (Right-to-Left) — suporte para idiomas onde o texto é lido da direita para a esquerda (árabe, hebraico, urdu, farsi). O Android suporta RTL através dos atributos android:layoutDirection e android:textDirection. No manifesto, especifique android:supportsRtl="true" — e o Android espelhará automaticamente o layout. NavDrawer, ícones de voltar/avançar, alinhamento de texto devem funcionar em ambas as direções. No código, use View.LAYOUT_DIRECTION_LOCALE e Gravity.START/END em vez de LEFT/RIGHT.
Android Resource Qualifiers permitem localizar não apenas strings, mas também imagens (res/drawable-ru/), layouts (res/layout-ru/), animações, cores. Para árabe e hebraico, são necessários layouts separados com elementos espelhados — use res/layout-ar/ (árabe). O Android também suporta variantes regionais: values-rUS, values-rGB, values-de-DE. Os qualificadores podem ser combinados: values-ldrtl-ru — russo para telas RTL.
Datas e hora — um dos aspectos chave do i18n. Diferentes regiões usam formatos diferentes: Rússia — DD.MM.AAAA, EUA — MM/DD/AAAA, Japão — AAAA.MM.DD. Usar um formato fixo (yyyy-MM-dd) para exibição ao usuário é um erro. No iOS, use DateFormatter com Locale(identifier: locale), no Android — DateFormat.getDateInstance(DateFormat.SHORT, locale). Para assistentes de voz e busca por IA, as datas devem estar em ISO 8601 internamente.
Números e moeda — regiões diferentes têm separadores diferentes: 1,234.56 (EUA) vs 1.234,56 (Rússia), 1 234,56 (França). iOS: NumberFormatter com .locale = locale. Android: DecimalFormat com DecimalFormatSymbols(locale). Para moedas: formato ¥1,234 (Japão) vs $1,234.56 (EUA) vs 1 234,56 ₽ (Rússia). Nunca concatene moeda e número manualmente — use NumberFormatter.currencyCode e .currencySymbol.
| Região | Data | Número | Moeda |
|---|---|---|---|
| Rússia | 31.12.2024 | 1 234,56 | 1 234,56 ₽ |
| EUA | 12/31/2024 | 1,234.56 | $1,234.56 |
| Alemanha | 31.12.2024 | 1.234,56 | 1.234,56 € |
| Japão | 2024/12/31 | 1,234 | ¥1,234 |
| Arábia Saudita | 31/12/2024 | 1,234.56 | 1,234.56 SAR |
Ordenação (Collation) — a ordenação alfabética difere entre idiomas. Em espanhol, "ch" vem depois de "c". Em sueco, "ä" está no final do alfabeto. Em alemão, "ß" é ordenado como "ss". iOS: LocalizedComparison (String.localizedCompare). Android: Collator.getInstance(locale). Nunca use compareTo() para strings exibidas ao usuário — ele usa a ordem Unicode Code Point, que não considera regras regionais.
Princípios arquiteturais — comece i18n desde o primeiro commit. Cada string no código deve passar por uma função wrapper (tr("key")) que não existe até que i18n seja configurado — isso força o desenvolvedor a externalizar strings imediatamente. Não use strings em inglês como chaves — quando a redação em inglês mudar, todas as traduções precisarão ser atualizadas. Use chaves significativas: "profile.title", "settings.language.label".
Pseudolocalização — uma técnica de teste de i18n antes da tradução real. Substitua cada letra latina por caracteres com diacríticos (á, é, ñ, ü) para verificar a codificação, adicione um prefixo [XXX] para verificar truncamento de strings. Xcode: esquemas de execução — pseudo-idioma "Double-Length Pseudolanguage". Android: Opções do Desenvolvedor — Forçar direção de layout RTL, escala de fonte do sistema até 200%. A pseudolocalização encontra 80% dos problemas de i18n sem envolvimento do tradutor.
Checklist i18n da IT Sectr — antes do lançamento verificamos: (1) não há strings hardcoded no código (exceção: logs), (2) plurais funcionam corretamente para todos os idiomas, (3) datas/números são formatados através da Locale API, (4) o layout é exibido corretamente em idiomas RTL, (5) strings não são truncadas na escala máxima, (6) a pseudolocalização não revelou erros, (7) todos os idiomas declarados nas lojas têm um conjunto completo de traduções.
Perguntas frequentes
i18n (internacionalização) — preparação do código: externalização de strings, suporte RTL, formatação. Feito pelo desenvolvedor uma vez. l10n (localização) — tradução de strings para um idioma específico. Feito pelo tradutor várias vezes para cada localidade. i18n é arquitetura, l10n é conteúdo. Sem i18n, a localização é impossível em princípio.
NSLocalizedString é uma macro que procura o valor por chave no Localizable.strings para a localidade atual do dispositivo. Se a tradução for encontrada, retorna-a. Se não, retorna a chave. Formato: NSLocalizedString("key", comment: "descrição"). Para formatação com parâmetros, use String.localizedStringWithFormat().
strings.xml — arquivo com traduções no diretório res/values/{lang}/. A versão base está em values/strings.xml, as traduções em values-ru/strings.xml. O código acessa através de getString(R.string.key). O Android seleciona automaticamente o arquivo apropriado com base no idioma do sistema. Para plurais, o recurso <plurals> é usado com qualificadores zero/one/few/many/other.
RTL (Right-to-Left) — direção de escrita para árabe, hebraico, urdu, farsi. Android: supportsRtl="true" no manifesto, android:layoutDirection, Gravity.START/END. iOS: UISemanticContentAttribute.forceLeftToRight para RTL forçado. O layout deve ser espelhado: menu à direita, texto — da direita para a esquerda, ícones de navegação — invertidos.
Para publicação global, o conjunto mínimo: inglês, espanhol, francês, alemão, japonês, chinês, coreano, português, russo, italiano. A App Store exige no mínimo localização em inglês. Cada localidade adicional expande o público potencial. Para um mercado local, 1–2 idiomas são suficientes.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também