Translate Localizable.strings without breaking a single %@
Upload en.lproj/Localizable.strings, pick locales, and get back de.lproj/Localizable.strings, ja.lproj/Localizable.strings… — every %@ and printf %d/%ld specifier lands exactly where NSLocalizedString expects it.
Upload Localizable.strings
Drop en.lproj/Localizable.strings in, or run kaeris translate en.lproj/Localizable.strings --langs de,ja,ar.
Pick target locales
46 languages, named to match Apple's language codes for your .lproj folders.
Ship
Rename each download's folder to de.lproj/, add it in Xcode's Localization settings, build.
Before → after
/* en */ "welcome" = "Welcome back, %@!"; "items_left" = "%d items left in stock"; "save" = "Save changes";
/* de */ "welcome" = "Willkommen zurück, %@!"; "items_left" = "Noch %d Artikel auf Lager"; "save" = "Änderungen speichern";
KAERIS translates the flat "key" = "value"; pairs that make up most of an app's copy — the same content NSLocalizedString(@"welcome", nil) reads at runtime. Quantity-aware variants that live in a .stringsdict or an Xcode 15+ String Catalog (.xcstrings) are a separate plist/JSON structure this pass doesn't rewrite yet — translate their string values individually for now.
%@ / %d / %ld printf-safe
Objective‑C/Swift format specifiers are never dropped, reordered or mistranslated across all 46 target locales.
NSLocalizedString-ready
Output is a real .strings file with correct quoting/escaping — drop it in and Xcode reads it as-is.
One file per locale
Each download is named for its language — rename the folder to <lang>.lproj and you're done.
One CLI command
kaeris translate en.lproj/Localizable.strings --langs de,ja,ar — scriptable straight into a Fastlane lane or CI job.
%@/%d is never dropped or mistranslated..strings out, correctly quoted, not a flattened wrapper.Ship your iOS app in every market
46 languages, printf-safe, .lproj-ready. Free to start, no account required.
$ pip install kaeris $ kaeris translate en.lproj/Localizable.strings --langs de,ja,ar