Глобализација (глобализација, такође интернационализација, i18n) — процес припреме мобилне апликације за рад са више језика и регионалних формата без промене изворног кода. Укључује издвајање текстуалних ресурса из кода, подршку за различите формате датума, бројева и валута, узимање у обзир смера текста (LTR/RTL) и адаптацију распореда за различите језике. У iOS-у се користе NSLocalizedString и Localizable.strings, у Android-у — strings.xml у директоријумима values-{lang}. Више у документацији Apple о интернационализацији.
Главно
Глобализација (скраћено i18n — 18 слова између «i» и «n») — архитектонска припрема апликације за рад са било којим језиком и регионом. Кључно правило i18n: ниједан текстуални стринг не сме бити чврсто кодиран (hardcoded) у изворном коду. Уместо тога, стрингови се издвајају у ресурсне датотеке, а код им приступа преко кључева. При додавању новог језика довољно је додати датотеку превода — код остаје непромењен. Ово разликује i18n од локализације (l10n), где се преводе сами стрингови.
Пословни аргумент — глобализација повећава тржиште. Према Common Sense Advisory (2023), више од 70% корисника преферира куповину у апликацијама на матерњем језику. Локализација на 10 језика повећава потенцијалну публику за 80%. Без i18n свако проширење на нови језик захтева дораду кода, што успорава излазак на тржиште и повећава трошак 5–10 пута. Исправна i18n архитектура омогућава подршку за 40+ језика уз минималне трошкове.
Компоненте i18n укључују: издвајање стрингова (String externalization), плурале (pluralization за 1/2/5+), форматирање датума и бројева (DateFormatter/SimpleDateFormat), подршку за RTL језике (Right-to-Left), сортирање по правилима локале (Collator), регионалне симболе (сепаратори хиљада, децимални знаци). У IT Sectr постављамо i18n у фази архитектуре, а не додајемо постфактум — ово штеди до 60% времена при каснијој локализацији.
NSLocalizedString — основни Swift макрос за рад са преводима. Формат: NSLocalizedString(«key», comment: «опис за преводиоца»). Макрос аутоматски замењује стринг из Localizable.strings за тренутну локалу уређаја (NSLocale.preferredLanguages). Ако превод за кључ није пронађен, враћа се сам кључ или вредност у development language (обично en). Apple препоручује коришћење смислених кључева, а не енглеских стрингова као кључева.
// Localizable.strings (en)
// "welcome_title" = "Добродошли!";
// Localizable.strings (ru)
// "welcome_title" = "Добродошли!";
// Swift код — јединствен за све језике
titleLabel.text = NSLocalizedString(
"welcome_title",
comment: "Наслов екрана добродошлице"
)
// Плурали преко Localizable.stringsdict
//
// <dict>
// <key>items_count</key>
// <dict>
// <key>NSStringLocalizedFormatKey</key>
// <string>%#@items@</string>
// <key>items</key>
// <dict>
// <key>one</key>
// <string>%d производ</string>
// <key>few</key>
// <string>%d производа</string>
// <key>many</key>
// <string>%d производа</string>
// </dict>
// </dict>
// </dict>
// Коришћење плурала
let items = 5
let label = String.localizedStringWithFormat(
NSLocalizedString("items_count", comment: ""), items
)
XLIFF — формат размене превода између програмера и преводилаца. Xcode извози XLIFF датотеку (Editor → Export for Localization) која садржи све стрингове за превод. Преводилац ради са XLIFF-ом у CAT алатима (Trados, memoQ, Smartcat). Након превода, XLIFF се увози назад у Xcode (Editor → Import Localizations). XLIFF аутоматски ажурира све .lproj директоријуме. Ово је стандардни радни ток локализације iOS апликација у продукцији.
SwiftUI ради са NSLocalizedString преко иницијализатора Text. Текст у SwiftUI-ју је аутоматски интернационализован: Text(«welcome_title») тражи превод у Localizable.strings исто као NSLocalizedString. За плурале користите Text(«%d items», count: items). SwiftUI подржава форматирање датума преко Text(date, style: .date) — аутоматски користи Locale.current. Apple препоручује SwiftUI за нове пројекте, јер је интернационализација у њему транспарентнија.
Android i18n се заснива на ресурсном систему. Стрингови се издвајају у res/values/strings.xml за подразумевани језик (обично енглески). За сваки језик се креира посебан директоријум: res/values-ru/strings.xml (руски), res/values-de/strings.xml (немачки), res/values-fr/strings.xml (француски). Android аутоматски бира стрингове на основу системског језика уређаја (Locale.getDefault()). Ако тачна локала не постоји, користи се базна верзија (values/strings.xml).
// res/values/strings.xml (енглески, подразумевани)
<resources>
<string name="welcome_title">Welcome!</string>
<string name="items_count">%d item(s)</string>
</resources>
// res/values-ru/strings.xml (руски)
<resources>
<string name="welcome_title">Добродошли!</string>
<plurals name="items_count">
<item quantity="one">%d производ</item>
<item quantity="few">%d производа</item>
<item quantity="many">%d производа</item>
</plurals>
</resources>
// Kotlin код
textView.text = getString(R.string.welcome_title)
// Плурали
val items = 5
textView.text = resources.getQuantityString(
R.plurals.items_count, items, items
)
// RTL подршка у коду
textView.textDirection = View.TEXT_DIRECTION_LOCALE
// Manifest: supportsRtl="true"
RTL (Right-to-Left) — подршка за језике где се текст чита здесна налево (арапски, хебрејски, урду, персијски). Android подржава RTL преко атрибута android:layoutDirection и android:textDirection. У манифесту наведите android:supportsRtl="true" — и Android аутоматски огледа распоред. NavDrawer, иконе назад/напред, поравнање текста треба да раде у оба смера. У коду користите View.LAYOUT_DIRECTION_LOCALE и Gravity.START/END уместо LEFT/RIGHT.
Android Resource Qualifiers омогућавају локализацију не само стрингова, већ и слика (res/drawable-ru/), распореда (res/layout-ru/), анимација, боја. За арапски и хебрејски су потребни одвојени распореди са огледалним распоредом елемената — користите res/layout-ar/ (арапски). Android такође подржава регионалне варијанте: values-rUS, values-rGB, values-de-DE. Qualifiers се комбинују: values-ldrtl-ru — руски за RTL дисплеје.
Датуми и време — један од кључних аспеката i18n. Различити региони користе различите формате: Русија — ДД.ММ.ГГГГ, САД — ММ/ДД/ГГГГ, Јапан — ГГГГ.ММ.ДД. Коришћење фиксног формата (yyyy-MM-dd) за приказ кориснику је грешка. У iOS-у користите DateFormatter са Locale(identifier: locale), у Android-у — DateFormat.getDateInstance(DateFormat.SHORT, locale). За гласовне асистенте и AI претрагу датуми треба да буду у ISO 8601 у унутрашњој репрезентацији.
Бројеви и валуте — у различитим регионима различити сепаратори: 1,234.56 (САД) vs 1.234,56 (Русија), 1 234,56 (Француска). iOS: NumberFormatter са .locale = locale. Android: DecimalFormat са DecimalFormatSymbols(locale). За валуте: формат ¥1,234 (Јапан) vs $1,234.56 (САД) vs 1 234,56 ₽ (Русија). Никада не конкатенирајте валуту и број ручно — користите NumberFormatter.currencyCode и .currencySymbol.
| Регион | Датум | Број | Валута |
|---|---|---|---|
| Русија | 31.12.2024 | 1 234,56 | 1 234,56 ₽ |
| САД | 12/31/2024 | 1,234.56 | $1,234.56 |
| Немачка | 31.12.2024 | 1.234,56 | 1.234,56 € |
| Јапан | 2024/12/31 | 1,234 | ¥1,234 |
| Саудијска Арабија | 31/12/2024 | 1,234.56 | 1,234.56 SAR |
Сортирање (Collation) — алфабетско сортирање се разликује у различитим језицима. У шпанском «ch» иде после «c». У шведском «ä» је на крају алфабета. У немачком «ß» се сортира као «ss». iOS: LocalizedComparison (String.localizedCompare). Android: Collator.getInstance(locale). Никада не користите compareTo() за стрингове приказане кориснику — он користи Unicode Code Point order, не узимајући у обзир регионална правила.
Архитектонски принципи — започните i18n од првог комита. Сваки стринг у коду треба да прође кроз функцију омотач (tr("key")), која не постоји док се i18n не подеси — ово ће натерати програмера да одмах издвоји стрингове. Не користите енглеске стрингове као кључеве — при промени формулације на енглеском мораћете да ажурирате све преводе. Користите смислене кључеве: «profile.title», «settings.language.label».
Псеудолокализација — техника тестирања i18n пре стварног превода. Замените свако латинично слово симболима са дијакритиком (á, é, ñ, ü) за проверу кодирања, додајте префикс [XXX] за проверу скраћивања стрингова. Xcode: шеме покретања — псеудојезик «Double-Length Pseudolanguage». Android: Developer Options — Force RTL layout direction, System font scale до 200%. Псеудолокализација проналази 80% проблема i18n без учешћа преводиоца.
IT Sectr чеклист i18n — пре издавања проверавамо: (1) нема hardcoded стрингова у коду (изузетак: логови), (2) плурали исправно раде за све језике, (3) датуми/бројеви се форматирају преко Locale API, (4) распоред се исправно приказује на RTL језицима, (5) стрингови се не скраћују при максималном скалирању, (6) псеудолокализација није открила грешке, (7) сви језици пријављени у продавницама имају комплетан скуп превода.
Често постављана питања
i18n (интернационализација) — припрема кода: издвајање стрингова, подршка за RTL, форматирање. Ради је програмер једном. l10n (локализација) — превођење стрингова на одређени језик. Ради преводилац више пута за сваку локализацију. i18n — архитектура, l10n — садржај. Без i18n локализација у принципу није могућа.
NSLocalizedString — макрос који тражи вредност по кључу у Localizable.strings за тренутну локалу уређаја. Ако превод пронађе — враћа га. Ако не — враћа кључ. Формат: NSLocalizedString(«key», comment: «опис»). За форматирање са параметрима користите String.localizedStringWithFormat().
strings.xml — датотека са преводима у директоријуму res/values/{lang}/. Базна верзија у values/strings.xml, преводи — у values-ru/strings.xml. Код приступа преко getString(R.string.key). Android сам бира потребну датотеку на основу системског језика. За плурале се користи ресурс <plurals> са спецификацијама zero/one/few/many/other.
RTL (Right-to-Left) — смер писања за арапски, хебрејски, урду, персијски. Android: supportsRtl="true" у манифесту, android:layoutDirection, Gravity.START/END. iOS: UISemanticContentAttribute.forceLeftToRight за присилни RTL. Распоред треба да се огледа: мени десно, текст — здесна налево, иконе навигације — обрнуте.
За глобално објављивање минимални скуп: енглески, шпански, француски, немачки, јапански, кинески, корејски, португалски, руски, италијански. App Store захтева најмање енглеску локализацију. Свака додатна локализација повећава потенцијалну публику. За локално тржиште довољно је 1–2 језика.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође