smithery/rektoooooo

ios-localization

iOS localization expert for internationalization. Use when working with String Catalogs, XLIFF, localized strings, date/number formatting, pluralization, or multi-language support.

Installation

$ npx skills add smithery/rektoooooo --skill ios-localization

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/rektoooooo · top by installs.

npx skills add smithery/rektoooooo

Browse all from smithery/rektoooooo

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,345 B
  • docs SUMMARY.md 204 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

iOS Localization

Expert guidance for localizing iOS applications.

String Catalogs (Xcode 15+)

Create String Catalog

  1. File > New > File > String Catalog
  2. Name it Localizable.xcstrings

Basic Usage

// SwiftUI - automatically extracted
Text("Hello, World!")
Text("Welcome to the app")

// With String Catalogs, strings are auto-extracted
// Edit translations directly in Xcode

String Interpolation

// Variable interpolation
Text("Hello, \(username)!")

// In String Catalog:
// Key: "Hello, %@!"
// Variations per language

// Multiple variables
Text("Score: \(points) points in \(level)")
// Key: "Score: %lld points in %@"

Comments for Translators

Text("Save", comment: "Button to save the current document")
Text("Book", comment: "Noun - a written publication, not the verb")

Pluralization

Automatic Pluralization

// In SwiftUI
Text("^[\(itemCount) item](inflect: true)")

// Handles:
// 0 items, 1 item, 2 items, etc.

Manual Pluralization (String Catalog)

Text("\(count) files selected")

// In String Catalog, create variations:
// zero: "No files selected"
// one: "1 file selected"
// other: "%lld files selected"

Complex Pluralization

// In String Catalog with substitutions
Text("\(unreadCount) unread messages from \(senderCount) senders")

// Variations handle both numbers independently

Localized Resources

Localized Images

// 1. Create asset catalog variations per language
// 2. Or use localized file names:
//    - welcome_en.png
//    - welcome_ja.png

Image("welcome", bundle: .main)
    .resizable()

Localized Colors

// In asset catalog, add appearances for languages
Color("brandColor")

Info.plist Localization

<!-- InfoPlist.strings (Localized) -->
<!-- English -->
"CFBundleDisplayName" = "My App";
"NSCameraUsageDescription" = "Take photos for your profile";

<!-- Japanese -->
"CFBundleDisplayName" = "マイアプリ";
"NSCameraUsageDescription" = "プロフィール写真を撮影";

Formatters

Date Formatting

// Automatic localization
Text(date, style: .date)
Text(date, style: .time)
Text(date, format: .dateTime.day().month().year())

// Custom format (still localized)
let formatter = DateFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .short
// Automatically uses device locale

// Relative dates
Text(date, format: .relative(presentation: .named))
// "yesterday", "2 days ago", etc.

Number Formatting

// Currency
Text(price, format: .currency(code: "USD"))
// $9.99 (US), 9,99 $ (France)

// Percentage
Text(progress, format: .percent)

// Decimal
Text(value, format: .number.precision(.fractionLength(2)))

// Measurement
let distance = Measurement(value: 5, unit: UnitLength.kilometers)
Text(distance, format: .measurement(width: .abbreviated))
// "5 km" or "3.1 mi" based on locale

List Formatting

let items = ["Apple", "Banana", "Orange"]
Text(items, format: .list(type: .and))
// "Apple, Banana, and Orange" (English)
// "Apple、Banana、Orange" (Japanese)

Layout Considerations

Right-to-Left Languages

// Automatic RTL support
HStack {
    Image(systemName: "arrow.left")
    Text("Back")
}
// Flips automatically for RTL

// Prevent flipping when needed
Image(systemName: "checkmark")
    .flipsForRightToLeftLayoutDirection(false)

Check Layout Direction

struct AdaptiveView: View {
    @Environment(\.layoutDirection) var layoutDirection

    var body: some View {
        HStack {
            if layoutDirection == .rightToLeft {
                trailingContent
                leadingContent
            } else {
                leadingContent
                trailingContent
            }
        }
    }
}

Text Alignment

// Use leading/trailing instead of left/right
Text("Content")
    .frame(maxWidth: .infinity, alignment: .leading)

// Multi-line alignment
Text("Long text content here")
    .multilineTextAlignment(.leading)

Language-Specific Adjustments

Check Current Language

let currentLanguage = Locale.current.language.languageCode?.identifier
// "en", "ja", "fr", etc.

if currentLanguage == "ja" {
    // Japanese-specific adjustments
}

Override Locale

// For testing
Text(date, format: .dateTime)
    .environment(\.locale, Locale(identifier: "ja_JP"))

// Preview in different locales
#Preview {
    ContentView()
        .environment(\.locale, Locale(identifier: "ar"))
        .environment(\.layoutDirection, .rightToLeft)
}

Export/Import

Export for Translation

# Command line
xcodebuild -exportLocalizations -project MyApp.xcodeproj -localizationPath ./Localizations

# Exports XLIFF files for each language

Import Translations

xcodebuild -importLocalizations -project MyApp.xcodeproj -localizationPath ./Localizations/ja.xcloc

Testing Localization

Preview Different Languages

#Preview("English") {
    ContentView()
        .environment(\.locale, Locale(identifier: "en"))
}

#Preview("Japanese") {
    ContentView()
        .environment(\.locale, Locale(identifier: "ja"))
}

#Preview("Arabic RTL") {
    ContentView()
        .environment(\.locale, Locale(identifier: "ar"))
        .environment(\.layoutDirection, .rightToLeft)
}

Pseudo-Localization

// In scheme settings:
// Edit Scheme > Run > Options
// - Application Language: Right-to-Left Pseudolanguage
// - Application Language: Accented Pseudolanguage (double-length)

UI Tests for Localization

func testLocalizedUI() {
    let app = XCUIApplication()
    app.launchArguments += ["-AppleLanguages", "(ja)"]
    app.launchArguments += ["-AppleLocale", "ja_JP"]
    app.launch()

    // Test Japanese UI
    XCTAssertTrue(app.buttons["保存"].exists)
}

Best Practices

String Keys

// Use descriptive keys in code
Text("welcome.message")
Text("button.save")
Text("error.network.unavailable")

// Actual translations in String Catalog

Avoid Concatenation

// Bad - breaks translation
Text("Hello, ") + Text(username) + Text("!")

// Good - single translatable string
Text("Hello, \(username)!")

Context for Translators

// Provide context
Text("Post", comment: "Verb - action to publish content")
Text("Post", comment: "Noun - a published article")

// Different keys for same word in different contexts
Text("settings.save.button") // "Save" button in settings
Text("document.save.action") // "Save" action for document

Apple Documentation