Localization
Skill markdavidgan/apple-dev-skills/platforms/kimi/skills/localization
Apple platform development skills for Claude Code, Cursor, Kimi Code, Antigravity, Codex CLI, and Agy.
npx -y skills add markdavidgan/apple-dev-skills --skill localizationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Localize and internationalize an app with String Catalogs (.xcstrings), correct pluralization and grammar agreement, RTL layout, locale-aware formatting, and pseudolocalization testing. Use when adding languages, translating UI, fixing plurals or gendered strings, supporting right-to-left languages, formatting dates/numbers/currency per locale, or producing localized screenshots. Trigger on "localization", "internationalization", "i18n", "String Catalog", ".xcstrings", "translate", "RTL", "plural", or "locale".
SKILL.md
5.0 KB, as published. Nobody here has run it
Localization & Internationalization
Make the app correct in every language — not just translated, but grammatical, well-formatted, and laid out right. Marketing/keyword localization for the store is asc-aso; this is the app itself.
String Catalogs (.xcstrings) — the modern way
Add a String Catalog (Localizable.xcstrings). Xcode extracts strings from Text("…"), String(localized:), and LocalizedStringResource automatically and tracks translation state per language.
Text("Welcome") // SwiftUI localizes automatically
let msg = String(localized: "Welcome") // non-SwiftUI code
let resource: LocalizedStringResource = "Welcome" // pass localizable strings around
- Give translators context with a comment:
Text("Open", comment: "Verb — opens the document"). "Open" the verb vs adjective translate differently. - Never build sentences by concatenation.
Text("You have \(n) items")is one interpolated key;Text("You have ") + Text("\(n)") + Text(" items")is untranslatable word-order garbage. - SwiftUI string literals are localized by default; non-literal
Text(someString)is not — wrap withLocalizedStringKey/String(localized:)deliberately.
Plurals & grammar agreement
Languages have 1–6 plural categories (English 2, Arabic 6, Japanese 1). Don't hand-roll if n == 1.
- In the String Catalog, set a key to vary by plural and provide the
zero/one/two/few/many/otherforms the language needs. The catalog applies the right one for the count automatically. - Use automatic grammar agreement for inflection:
^[\(count) item](inflect: true)pluralizes the noun to match the number in supported languages. - Vary strings by device (iPhone vs iPad wording) and by gender/term where the catalog supports it.
Right-to-left (RTL)
- Use leading/trailing, never left/right, in layout and padding — SwiftUI then mirrors automatically for Arabic/Hebrew.
- Mirror directional SF Symbols correctly (most do automatically; check chevrons/arrows).
- Test by forcing it: scheme → Run → Options → App Language: Right-to-Left Pseudolanguage, or
.environment(\.layoutDirection, .rightToLeft)in a preview. - Numbers, code, and some content stay LTR inside RTL text — let the system handle bidi; don't reorder manually.
Locale-aware formatting (never format by hand)
let price = 12.5.formatted(.currency(code: "EUR")) // "12,50 €" in de, "€12.50" in en
let when = date.formatted(.dateTime.weekday().hour()) // locale order & 12/24h
let count = 5.formatted() // grouping separators per locale
let dist = Measurement(value: 5, unit: UnitLength.kilometers).formatted() // mi vs km
- Decimal/grouping separators, currency placement, first day of week, 12/24h, and units all vary by locale —
.formatted()/FormatStylehandle them. ManualString(format:)for numbers/dates is a localization bug. - Don't assume currency from language; price comes from the storefront (see
app-store-pricing).
Pseudolocalization — find bugs before translators do
Run with Xcode's built-in pseudolanguages (scheme → Options → App Language):
- Accented Pseudolanguage — surfaces hard-coded (non-localized) strings; they stay plain ASCII.
- Double-Length Pseudolanguage — German/Finnish run ~30–40% longer; truncation and clipped buttons show up immediately.
- Right-to-Left Pseudolanguage — catches left/right layout assumptions.
Also enable Show non-localizable strings to flag literals you forgot to wrap.
Screenshots & assets
- Generate localized screenshots by running UI tests per language (
xcodebuild ... -testLanguage de -testRegion DE, or fastlane snapshot) and upload per locale (seeasc-submission). Seeios-simulatefor the capture harness. - Localize images/audio that contain text via asset catalog localization or
Bundlelookups; in SPM useBundle.module.
Pre-ship checklist
- All user-facing strings in the String Catalog (no literals — pseudoloc clean).
- Plurals use catalog variations /
inflect:, notif n == 1. - Layout uses leading/trailing; RTL pseudolanguage looks right.
- Dates/numbers/currency via
.formatted()/FormatStyle. - Double-length pseudolanguage shows no truncation.
- Dynamic Type still fits at the longest language (cross-check
ios-accessibility). - Localized screenshots/metadata per shipped locale.