ios-localization
The ios-localization Claude Code skill provides implementation guidance for multi-language iOS and macOS app support using String Catalogs, modern string types, FormatStyle, and right-to-left layout techniques. Use it when adding internationalization to new or existing iOS 26+ projects, setting up compile-time-safe localization keys, handling pluralization, formatting dates and numbers for different locales, or ensuring UI adapts correctly for RTL languages like Arabic and Hebrew.
git clone --depth 1 https://github.com/dpearson2699/swift-ios-skills /tmp/ios-localization && cp -r /tmp/ios-localization/skills/ios-localization ~/.claude/skills/ios-localizationSKILL.md
# iOS Localization & Internationalization
Localize iOS 26+ apps using String Catalogs, modern string types, FormatStyle, and RTL-aware layout. Localization mistakes cause App Store rejections in non-English markets, mistranslated UI, and broken layouts. Ship with correct localization from the start.
## Contents
- [String Catalogs (.xcstrings)](#string-catalogs-xcstrings)
- [String Catalogs (Xcode 15+) and Generated Symbols (Xcode 26+)](#string-catalogs-xcode-15-and-generated-symbols-xcode-26)
- [String Types -- Decision Guide](#string-types-decision-guide)
- [String Interpolation in Localized Strings](#string-interpolation-in-localized-strings)
- [Pluralization](#pluralization)
- [FormatStyle -- Locale-Aware Formatting](#formatstyle-locale-aware-formatting)
- [Right-to-Left (RTL) Layout](#right-to-left-rtl-layout)
- [Common Mistakes](#common-mistakes)
- [Localization Review Checklist](#review-checklist)
- [References](#references)
## String Catalogs (.xcstrings)
String Catalogs are the recommended Xcode 15+ workflow for new localization work. They keep localizable strings, pluralization rules, and device variations together in an Xcode-managed JSON file with a visual editor. Legacy `.strings` and `.stringsdict` files can coexist during migration, but new Swift and SwiftUI code should default to String Catalogs.
**Why String Catalogs exist:**
- `.strings` files required manual key management and fell out of sync
- `.stringsdict` required complex XML for plurals
- String Catalogs auto-extract strings from code, track translation state, and support plurals natively
**How automatic extraction works:**
Xcode scans for these patterns on each build:
```swift
// SwiftUI -- automatically extracted (LocalizedStringKey)
Text("Welcome back") // key: "Welcome back"
Label("Settings", systemImage: "gear")
Button("Save") { }
Toggle("Dark Mode", isOn: $dark)
// Programmatic -- automatically extracted
String(localized: "No items found")
LocalizedStringResource("Order placed")
// NOT extracted -- plain String, not localized
let msg = "Hello" // just a String, invisible to Xcode
```
Xcode adds discovered keys to the String Catalog automatically. Mark translations as Needs Review, Translated, or Stale in the editor.
For detailed String Catalog workflows, migration, and testing strategies, see [references/string-catalogs.md](references/string-catalogs.md).
## String Catalogs (Xcode 15+) and Generated Symbols (Xcode 26+)
For generated-symbol or migration answers, start by stating: "String Catalogs are the recommended Xcode 15+ localization workflow. Xcode 26 generated symbols are a separate typed-access layer on top of String Catalogs." Then explain generated symbols, plurals, or migration details. Do not describe catalogs themselves as requiring Xcode 26 or iOS 17.
**Enable:** Build Settings > Localization > Generate String Catalog Symbols → `Yes` (on by default in new Xcode 26 projects). Requires catalog format version `1.1`.
**Workflow:** Add a key manually via the (+) button in the String Catalog editor — manual keys have the **Generate Swift Symbol** checkbox enabled by default. Auto-extracted keys can also opt in via Refactor > Convert Strings to Symbols. Use stable manual keys for generated-symbol strings. Avoid source-copy-derived keys for API-facing strings because wording edits can rename generated identifiers and churn call sites.
```swift
// Generated from key "room_available" in Localizable.xcstrings
Text(.roomAvailable)
// Parameterized key "landmarks_count" with %1$(count)lld
Text(.landmarksCount(count: 42))
// Non-default table "Booking.xcstrings"
Text(.Booking.confirmBookingCta)
```
Xcode derives symbol names by camelCasing the key: `settings.notifications.toggle` → `.settingsNotificationsToggle`. You can convert existing extracted strings to symbols via Refactor > Convert Strings to Symbols (reversible).
Generated symbols are `internal`. For cross-module access, create a public wrapper extension. For heavier multi-module setups, use [xcstrings-tool](https://github.com/liamnichols/xcstrings-tool) instead.
For the full generated symbols reference — extraction states, symbol derivation rules, and cross-module patterns — see [references/string-catalogs.md](references/string-catalogs.md).
## String Types -- Decision Guide
### LocalizedStringKey (SwiftUI default)
SwiftUI views accept `LocalizedStringKey` for their text parameters. String literals are implicitly converted -- no extra work needed.
```swift
// These all create a LocalizedStringKey lookup automatically:
Text("Welcome back")
Label("Profile", systemImage: "person")
Button("Delete") { deleteItem() }
.navigationTitle("Home")
```
Use `LocalizedStringKey` when passing strings directly to SwiftUI view initializers. Do not construct `LocalizedStringKey` manually in most cases.
### String(localized:) -- Modern NSLocalizedString replacement
Use for any localized string outside a SwiftUI view initializer. Returns a plain `String`. The literal/interpolated initializer is available iOS 15+; resolving a `LocalizedStringResource` is iOS 16+.
```swift
// Basic
let title = String(localized: "Welcome back")
// With default value (key differs from English text)
let msg = String(localized: "error.network",
defaultValue: "Check your internet connection")
// With table and bundle
let label = String(localized: "onboarding.title",
table: "Onboarding",
bundle: .module)
// With comment for translators
let btn = String(localized: "Save",
comment: "Button title to save the current document")
```
For Swift package localization failures, answer with this explicit resource checklist before bundle debugging:
1. `Package.swift` declares `defaultLocalization`.
2. The target `resources` list processes the catalog location, such as `.process("Resources")`.
3. `Localizable.xcstrings` is actually inside that processed target-resource pathDiscover and configure Bluetooth and Wi-Fi accessories using AccessorySetupKit. Use when presenting a privacy-preserving accessory picker, defining discovery descriptors for BLE or Wi-Fi devices, handling accessory session events, migrating from CoreBluetooth permission-based scanning, or setting up accessories without requiring broad Bluetooth permissions.
Implement, review, or improve Live Activities and Dynamic Island experiences in iOS apps using ActivityKit. Use when building real-time updating widgets for the Lock Screen and Dynamic Island — delivery tracking, sports scores, ride-sharing status, workout timers, media playback, or any time-sensitive information that updates in real time. Also use when working with ActivityKit, ActivityAttributes, Activity lifecycle (request/update/end), Dynamic Island layouts (compact/minimal/expanded), push-to-update Live Activities, or Lock Screen live widgets.
Measure ad effectiveness with privacy-preserving attribution using AdAttributionKit. Use when registering ad impressions, handling attribution postbacks, updating conversion values, implementing re-engagement attribution, configuring publisher or advertiser apps, or replacing SKAdNetwork with AdAttributionKit for ad measurement.
Implement AlarmKit alarms and countdown timers for iOS and iPadOS with Lock Screen, Dynamic Island, StandBy, and paired Apple Watch system UI. Covers AlarmManager scheduling, AlarmAttributes and AlarmPresentation, AlarmButton stop and snooze actions, authorization, state observation, countdown widget-extension handoff, and Live Activity integration. Use when building wake-up alarms, countdown timers, or alarm-style alerts that need Apple's system alarm experience.
Build iOS App Clips with invocation URLs, App Clip Codes, NFC, QR codes, Safari banners, Maps, Messages, target setup, App Store Connect experiences, size/capability constraints, NSUserActivity routing, SKOverlay promotion, App Group/keychain handoff, ephemeral notifications, location confirmation, and full-app migration. Use when creating App Clips or wiring App Clip invocation, experience configuration, or full-app handoff.
Implement App Intents for Siri, Shortcuts, Spotlight, widgets, Control Center, and Apple Intelligence on iOS. Covers AppIntent actions, AppEntity and EntityQuery models, AppShortcutsProvider phrases, IndexedEntity Spotlight indexing, WidgetConfigurationIntent, SnippetIntent, and assistant schemas. Use when exposing app actions or entities to system surfaces.
Optimize App Store product pages for search visibility and conversion. Use for App Store Optimization (ASO), keyword research, app name/subtitle/keyword-field strategy, conversion-focused descriptions and promotional text, screenshot captions and ordering, Custom Product Pages with assigned search keywords, In-App Events, Product Page Optimization tests, localized metadata, ratings/review strategy, and in-app review prompt timing with RequestReviewAction or AppStore.requestReview. Also use when routing ASO vs App Store review, privacy/ATT, or StoreKit implementation boundaries.
Prepare for App Store review and prevent rejections. Covers App Store review guidelines, app rejection reasons, PrivacyInfo.xcprivacy privacy manifest requirements, required API reason codes, in-app purchase IAP and StoreKit rules, App Store Guidelines compliance, ATT App Tracking Transparency, EU DMA Digital Markets Act, HIG compliance checklist, app submission preparation, review preparation, metadata requirements, entitlements, widgets, and Live Activities review rules. Use when preparing for App Store submission, fixing rejection reasons, auditing privacy manifests, implementing ATT consent flow, configuring StoreKit IAP, or checking HIG compliance.