Globalizacja: co to jest, i18n i wielojęzyczność w aplikacjach

Autor: IT Sectr Opublikowano: 2026-02-26 Czas czytania: 8 min

Globalizacja (globalizacja, także internacjonalizacja, i18n) — proces przygotowania aplikacji mobilnej do pracy z wieloma językami i formatami regionalnymi bez zmiany kodu źródłowego. Obejmuje wyodrębnienie zasobów tekstowych z kodu, obsługę różnych formatów dat, liczb i walut, uwzględnienie kierunku tekstu (LTR/RTL) i adaptację układu do różnych języków. W iOS używane są NSLocalizedString i Localizable.strings, w Android — strings.xml w katalogach values-{lang}. Więcej w dokumentacji Apple dotyczącej internacjonalizacji.

Najważniejsze

  • Globalizacja (i18n) — przygotowanie kodu aplikacji do wielu języków i regionów
  • NSLocalizedString — makro Swift do pobierania przetłumaczonych stringów z Localizable.strings
  • strings.xml — plik XML Androida, w którym przechowywane są zasoby tekstowe dla każdego języka
  • RTL — obsługa języków pisanych od prawej do lewej (arabski, hebrajski, urdu)
  • Formaty — daty, liczby i waluty powinny być formatowane przez API zależne od Locale

Czym jest globalizacja (i18n) i dlaczego jest potrzebna?

Globalizacja (w skrócie i18n — 18 liter między «i» a «n») — architektoniczne przygotowanie aplikacji do pracy z dowolnym językiem i regionem. Kluczowa zasada i18n: żaden ciąg tekstowy nie powinien być zakodowany na sztywno (hardcoded) w kodzie źródłowym. Zamiast tego stringi są wyodrębniane do plików zasobów, a kod odwołuje się do nich za pomocą kluczy. Przy dodawaniu nowego języka wystarczy dodać plik tłumaczenia — kod pozostaje niezmieniony. To odróżnia i18n od lokalizacji (l10n), gdzie tłumaczone są same stringi.

Argument biznesowy — globalizacja zwiększa rynek. Według Common Sense Advisory (2023), ponad 70% użytkowników woli kupować w aplikacjach w swoim ojczystym języku. Lokalizacja na 10 języków zwiększa potencjalną publiczność o 80%. Bez i18n każde rozszerzenie o nowy język wymaga modyfikacji kodu, co spowalnia wejście na rynek i zwiększa koszt 5–10 razy. Poprawna architektura i18n pozwala obsługiwać 40+ języków przy minimalnych kosztach.

Komponenty i18n obejmują: wyodrębnianie stringów (String externalization), formy liczby mnogiej (pluralization dla 1/2/5+), formatowanie dat i liczb (DateFormatter/SimpleDateFormat), obsługę języków RTL (Right-to-Left), sortowanie według reguł locale (Collator), symbole regionalne (separatory tysięcy, znaki dziesiętne). W IT Sectr uwzględniamy i18n na etapie architektury, a nie dodajemy po fakcie — to oszczędza do 60% czasu przy późniejszej lokalizacji.

Internacjonalizacja w iOS: NSLocalizedString i XLIFF

NSLocalizedString — główne makro Swift do pracy z tłumaczeniami. Format: NSLocalizedString(«key», comment: «opis dla tłumacza»). Makro automatycznie podstawia string z Localizable.strings dla bieżącego locale urządzenia (NSLocale.preferredLanguages). Jeśli tłumaczenie dla klucza nie zostanie znalezione, zwracany jest sam klucz lub wartość w development language (zwykle en). Apple zaleca używanie znaczących kluczy, a nie angielskich stringów jako kluczy.

swift
// Localizable.strings (en)
// "welcome_title" = "Witamy!";
// Localizable.strings (ru)
// "welcome_title" = "Witamy!";

// Kod Swift — jeden dla wszystkich języków
titleLabel.text = NSLocalizedString(
    "welcome_title",
    comment: "Nagłówek ekranu powitalnego"
)

// Formy liczby mnogiej przez Localizable.stringsdict
// 
// <dict>
//     <key>items_count</key>
//     <dict>
//         <key>NSStringLocalizedFormatKey</key>
//         <string>%#@items@</string>
//         <key>items</key>
//         <dict>
//             <key>one</key>
//             <string>%d produkt</string>
//             <key>few</key>
//             <string>%d produkty</string>
//             <key>many</key>
//             <string>%d produktów</string>
//         </dict>
//     </dict>
// </dict>

// Użycie form liczby mnogiej
let items = 5
let label = String.localizedStringWithFormat(
    NSLocalizedString("items_count", comment: ""), items
)

XLIFF — format wymiany tłumaczeń między programistami a tłumaczami. Xcode eksportuje plik XLIFF (Editor → Export for Localization), który zawiera wszystkie stringi do tłumaczenia. Tłumacz pracuje z XLIFF w narzędziach CAT (Trados, memoQ, Smartcat). Po tłumaczeniu XLIFF jest importowany z powrotem do Xcode (Editor → Import Localizations). XLIFF automatycznie aktualizuje wszystkie katalogi .lproj. To standardowy proces pracy nad lokalizacją aplikacji iOS w produkcji.

SwiftUI i i18n

SwiftUI współpracuje z NSLocalizedString przez inicjalizator Text. Tekst w SwiftUI jest automatycznie umiędzynarodowiony: Text(«welcome_title») szuka tłumaczenia w Localizable.strings tak samo jak NSLocalizedString. Dla form liczby mnogiej użyj Text(«%d items», count: items). SwiftUI obsługuje formatowanie dat przez Text(date, style: .date) — automatycznie używa Locale.current. Apple zaleca SwiftUI dla nowych projektów, ponieważ internacjonalizacja w nim jest bardziej przejrzysta.

Internacjonalizacja w Android: strings.xml i RTL

Android i18n opiera się na systemie zasobów. Stringi są wyodrębniane do res/values/strings.xml dla domyślnego języka (zwykle angielskiego). Dla każdego języka tworzony jest osobny katalog: res/values-ru/strings.xml (rosyjski), res/values-de/strings.xml (niemiecki), res/values-fr/strings.xml (francuski). Android automatycznie wybiera stringi na podstawie języka systemowego urządzenia (Locale.getDefault()). Jeśli nie ma dokładnego locale, podstawiana jest bazowa wersja (values/strings.xml).

kotlin
// res/values/strings.xml (angielski, domyślnie)
<resources>
    <string name="welcome_title">Welcome!</string>
    <string name="items_count">%d item(s)</string>
</resources>

// res/values-ru/strings.xml (rosyjski)
<resources>
    <string name="welcome_title">Witamy!</string>
    <plurals name="items_count">
        <item quantity="one">%d produkt</item>
        <item quantity="few">%d produkty</item>
        <item quantity="many">%d produktów</item>
    </plurals>
</resources>

// Kod Kotlin
textView.text = getString(R.string.welcome_title)

// Formy liczby mnogiej
val items = 5
textView.text = resources.getQuantityString(
    R.plurals.items_count, items, items
)

// Obsługa RTL w kodzie
textView.textDirection = View.TEXT_DIRECTION_LOCALE
// Manifest: supportsRtl="true"

RTL (Right-to-Left) — obsługa języków, w których tekst czyta się od prawej do lewej (arabski, hebrajski, urdu, perski). Android obsługuje RTL przez atrybuty android:layoutDirection i android:textDirection. W manifeście ustaw android:supportsRtl="true" — a Android automatycznie odbija layout. NavDrawer, ikony wstecz/do przodu, wyrównanie tekstu powinny działać w obie strony. W kodzie używaj View.LAYOUT_DIRECTION_LOCALE i Gravity.START/END zamiast LEFT/RIGHT.

Zlokalizowane zasoby

Android Resource Qualifiers pozwalają lokalizować nie tylko stringi, ale także obrazy (res/drawable-ru/), layouty (res/layout-ru/), animacje, kolory. Dla arabskiego i hebrajskiego potrzebne są osobne layouty z lustrzanym rozmieszczeniem elementów — użyj res/layout-ar/ (arabski). Android obsługuje również warianty regionalne: values-rUS, values-rGB, values-de-DE. Qualifiers łączą się: values-ldrtl-ru — rosyjski dla wyświetlaczy RTL.

Formaty regionalne: daty, liczby, waluty w iOS i Android

Daty i czas — jeden z kluczowych aspektów i18n. Różne regiony używają różnych formatów: Rosja — DD.MM.RRRR, USA — MM/DD/RRRR, Japonia — RRRR.MM.DD. Używanie stałego formatu (yyyy-MM-dd) do wyświetlania użytkownikowi — błąd. W iOS używaj DateFormatter z Locale(identifier: locale), w Android — DateFormat.getDateInstance(DateFormat.SHORT, locale). Dla asystentów głosowych i wyszukiwania AI daty powinny być w ISO 8601 w wewnętrznej reprezentacji.

Liczby i waluta — w różnych regionach różne separatory: 1,234.56 (USA) vs 1.234,56 (Rosja), 1 234,56 (Francja). iOS: NumberFormatter z .locale = locale. Android: DecimalFormat z DecimalFormatSymbols(locale). Dla walut: format ¥1,234 (Japonia) vs $1,234.56 (USA) vs 1 234,56 ₽ (Rosja). Nigdy nie konkatenuj waluty i liczby ręcznie — używaj NumberFormatter.currencyCode i .currencySymbol.

RegionDataLiczbaWaluta
Rosja31.12.20241 234,561 234,56 ₽
USA12/31/20241,234.56$1,234.56
Niemcy31.12.20241.234,561.234,56 €
Japonia2024/12/311,234¥1,234
Arabia Saudyjska31/12/20241,234.561,234.56 SAR

Sortowanie (Collation) — sortowanie alfabetyczne różni się w różnych językach. W hiszpańskim «ch» występuje po «c». W szwedzkim «ä» — na końcu alfabetu. W niemieckim «ß» sortuje się jak «ss». iOS: LocalizedComparison (String.localizedCompare). Android: Collator.getInstance(locale). Nigdy nie używaj compareTo() dla stringów wyświetlanych użytkownikowi — używa on Unicode Code Point order, nie uwzględniającego reguł regionalnych.

Najlepsze praktyki internacjonalizacji aplikacji mobilnych

Zasady architektoniczne — zaczynaj i18n od pierwszego commita. Każdy string w kodzie powinien przejść przez funkcję opakowującą (tr("key")), która nie istnieje przed skonfigurowaniem i18n — to zmusi programistę do wyodrębniania stringów od razu. Nie używaj angielskich stringów jako kluczy — przy zmianie sformułowania po angielsku trzeba będzie zaktualizować wszystkie tłumaczenia. Używaj znaczących kluczy: «profile.title», «settings.language.label».

Pseudolokalizacja — technika testowania i18n przed rzeczywistym tłumaczeniem. Zastąp każdą literę łacińską symbolem z diakrytyką (á, é, ñ, ü) do sprawdzenia kodowania, dodaj prefiks [XXX] do sprawdzenia obcinania stringów. Xcode: schematy uruchamiania — pseudojęzyk «Double-Length Pseudolanguage». Android: Developer Options — Force RTL layout direction, System font scale do 200%. Pseudolokalizacja znajduje 80% problemów i18n bez udziału tłumacza.

Lista kontrolna IT Sectr i18n — przed wydaniem sprawdzamy: (1) brak hardcoded stringów w kodzie (wyjątek: logi), (2) formy liczby mnogiej działają poprawnie dla wszystkich języków, (3) daty/liczby są formatowane przez Locale API, (4) layout poprawnie wyświetla się w językach RTL, (5) stringi nie są obcinane przy maksymalnym skalowaniu, (6) pseudolokalizacja nie wykazała błędów, (7) wszystkie języki zadeklarowane w sklepach mają kompletny zestaw tłumaczeń.

Często zadawane pytania

Czym i18n różni się od l10n?

i18n (internacjonalizacja) — przygotowanie kodu: wyodrębnianie stringów, obsługa RTL, formatowanie. Wykonywane przez programistę raz. l10n (lokalizacja) — tłumaczenie stringów na konkretny język. Wykonywane przez tłumacza wielokrotnie dla każdej lokalizacji. i18n — architektura, l10n — treść. Bez i18n lokalizacja jest w ogóle niemożliwa.

Jak działa NSLocalizedString w Swift?

NSLocalizedString — makro, które szuka wartości po kluczu w Localizable.strings dla bieżącego locale urządzenia. Jeśli tłumaczenie zostanie znalezione — zwraca je. Jeśli nie — zwraca klucz. Format: NSLocalizedString(«key», comment: «opis»). Do formatowania z parametrami użyj String.localizedStringWithFormat().

Jak zorganizowane są strings.xml w Android?

strings.xml — plik z tłumaczeniami w katalogu res/values/{lang}/. Bazowa wersja w values/strings.xml, tłumaczenia — w values-ru/strings.xml. Kod odwołuje się przez getString(R.string.key). Android sam wybiera odpowiedni plik na podstawie języka systemowego. Dla form liczby mnogiej używany jest zasób <plurals> z kwalifikatorami zero/one/few/many/other.

Czym jest RTL w kontekście i18n?

RTL (Right-to-Left) — kierunek pisma dla arabskiego, hebrajskiego, urdu, perskiego. Android: supportsRtl="true" w manifeście, android:layoutDirection, Gravity.START/END. iOS: UISemanticContentAttribute.forceLeftToRight dla wymuszonego RTL. Layout powinien odbijać się lustrzanie: menu po prawej, tekst — od prawej do lewej, ikony nawigacji — odwrócone.

Które języki są obowiązkowe do publikacji?

Do globalnej publikacji minimalny zestaw: angielski, hiszpański, francuski, niemiecki, japoński, chiński, koreański, portugalski, rosyjski, włoski. App Store wymaga co najmniej lokalizacji angielskiej. Każda dodatkowa lokalizacja zwiększa potencjalną publiczność. Dla lokalnego rynku wystarczy 1–2 języki.

Podsumowanie

  • Globalizacja (i18n) — architektoniczne przygotowanie aplikacji do wielu języków i regionów
  • NSLocalizedString — makro Swift do tłumaczenia stringów przez Localizable.strings + eksport XLIFF
  • strings.xml — zasób Androida z tłumaczeniami w katalogach values-{lang}
  • RTL — obowiązkowa obsługa dla arabskiego, hebrajskiego, urdu i perskiego
  • Formaty — daty i liczby są formatowane ściśle przez Locale API, nie ręcznie
  • Formy liczby mnogiej — iOS: stringsdict, Android: <plurals> z sześcioma formami ilości
  • Pseudolokalizacja — technika testowania i18n przed tłumaczeniem (wykrywa 80% problemów)

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również