Ios localization
Skill almasumdev/awesome-ios-agent-skills/.github/skills/ui/ios-localization
Curated agent skills, conventions, and workflows for building iOS apps (Swift, SwiftUI, UIKit) with AI coding agents.
npx -y skills add almasumdev/awesome-ios-agent-skills --skill ios-localizationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 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
Expert guidance on iOS localization — String Catalogs (.xcstrings), ICU plurals and genders, right-to-left layout, and dynamic locale switching. Use when adding or auditing translated content.
SKILL.md
4.0 KB, as published. Nobody here has run it
iOS Localization & Internationalization
Instructions
Use String Catalogs (.xcstrings, Xcode 15+). They replace Localizable.strings + .stringsdict, support ICU plurals natively, and sync keys automatically.
1. String Catalog Basics
- File → New → File → String Catalog. Name it
Localizable.xcstrings. - Any
String(localized:)orText(_:)literal is extracted on build. - Add locales from the catalog's inspector; Xcode fills keys on build.
Text("article.save.button") // Key-based
Text("Save") // String-based (auto-extracted)
String(localized: "greeting.hello", defaultValue: "Hello, World")
Prefer semantic keys ("article.title.placeholder") over raw English for anything that might be rephrased.
2. Interpolation
let name = "Sam"
Text("greeting.user \(name)")
// Catalog entry: "greeting.user %@" → "Hello, %@!"
For numbers and dates, use format specifiers or FormatStyle:
Text("\(count, format: .number)")
Text("\(date, format: .dateTime.day().month().year())")
Text("\(amount, format: .currency(code: "USD"))")
3. Plurals (ICU)
String Catalogs expose a Vary by Plural option directly in the editor. Under the hood:
Text("inbox.unread \(count)")
// "one" -> "1 unread message"
// "other" -> "%lld unread messages"
For older codebases, a .stringsdict with the NSStringLocalizedFormatKey still works.
4. Gender and Width Variants
String Catalogs support device variants (iPhone/iPad/Mac/watch) and width classes. Use them for titles that need shorter forms on compact layouts:
profile.title
default: "Your Profile"
compact: "Profile"
5. Right-to-Left (RTL)
SwiftUI mirrors automatically when the locale is RTL. Write layouts with leading/trailing, never left/right:
HStack { Image(systemName: "chevron.backward"); Text("Back") }
.padding(.leading, 16)
Force a preview:
#Preview("Arabic") {
RootView()
.environment(\.locale, .init(identifier: "ar"))
.environment(\.layoutDirection, .rightToLeft)
}
Use .flipsForRightToLeftLayoutDirection(true) on custom drawings (e.g., arrows) that must mirror.
6. Dynamic Locale Switching
The OS drives the locale, but apps can override per-scene:
struct RootView: View {
@AppStorage("preferredLanguage") private var lang: String = ""
var body: some View {
ContentView()
.environment(\.locale, lang.isEmpty ? .autoupdatingCurrent : Locale(identifier: lang))
}
}
To persist beyond the current scene, set UserDefaults "AppleLanguages" (requires restart to fully apply across all frameworks).
7. Formatting Rules
- Never concatenate translated strings — always interpolate.
- Never assume word order; give translators full sentences.
- Always provide context via the
comment:parameter:
String(localized: "cart.checkout.cta",
defaultValue: "Check out",
comment: "Button title on the cart screen confirming purchase.")
8. Testing
- Run with Double-Length Pseudolanguage and Right-to-Left Pseudolanguage to surface layout bugs.
- Snapshot tests in every locale you ship — see the
ios-testingskill. - Lint for hardcoded strings using SwiftLint rule
strict_fileprivateand custom rules.
Checklist
- All user-visible strings come from
String(localized:)/Text. - String Catalog is the single source of truth; no loose
.stringsfiles for new modules. - Plurals use catalog variants, never string concatenation.
- Layouts use leading/trailing; custom drawings mirror for RTL.
- Every key has a translator-facing
comment:. - Pseudolanguage tests pass.