Skip to main content

translation

Translate strings in Xcode String Catalogs (.xcstrings files). Prefer to use the `xcode-integration:translation-coordinator` skill for task-coordination. Use this skill when translating individual strings or working with String Catalogs. Should only be activated when translating a single string or a small batch of known string keys. The `translation-coordinator` skill should be used for anything else.

Source facts

Repository
ankb90/ios-cli
Last source activity
November 9, 2026 at 05:03
Detected SKILL.md language
English
Stars
0
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
59 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
translation
sfSymbolName
translate
displayName
Translate Strings
description
Translate strings in Xcode String Catalogs (.xcstrings files). Prefer to use the `xcode-integration:translation-coordinator` skill for task-coordination. Use this skill when translating individual strings or working with String Catalogs. Should only be activated when translating a single string or a small batch of known string keys. The `translation-coordinator` skill should be used for anything else.
# String Catalog Translator Translate a given set of strings in Xcode String Catalogs using specialized MCP tools. These strings are user-facing software strings for apps on Apple platforms — typically short UI text such as button titles, labels, and messages. Translate them as you would for a native app on those platforms. Access String Catalogs **only** through these tools—never write .xcstrings files directly. Abort if no list of keys was provided, or if no target locale identifier was provided — something went wrong. Do not guess a locale from examples; the target locale must come from your initial instructions. ## Role Boundaries A specific list of string keys and a target locale identifier have been provided via your initial instructions. - Do not fetch additional string keys beyond what you were given - Do not translate into any locale other than the one explicitly provided - Do not use `LocalizationPlanner` (your coordinator already ran it) - Do not spawn sub-agents of your own ## Quick Reference | Tool | Purpose | |------|---------| | `StringCatalogRead` | Get string keys by translation state (new, needs_review, translated, machine_translated) | | `StringCatalogContext` | Get source value and context: comments, similar strings, code locations, plural cases | | `StringCatalogEdit` | Insert the translation | ## Workflow Skip the `LocalizationPlanner` tool when told to do so. For each string, **one at a time**, follow these steps in order. **Step 1: Get source value and context** Call `StringCatalogContext` with the target locale. The `sourceValues` field in the response contains the text that must be translated. The rest of the response provides context: - Developer comments explaining intent - Existing translations in other languages - Similar strings with their translations (for terminology consistency) - Code locations where the string is used - UI appearance hints (button vs. label affects verb/noun choice) - Required plural cases for the target locale **Step 2: Read the source code** at the provided file paths to understand how the string is used. This reveals the developer's intention and helps you choose the right translation (e.g., a verb for buttons, descriptive for labels). For instance, the key "Save" could be a verb (button action → "Speichern") or a noun (a save file → "Spielstand") — only the source code reveals which. Reading the source code is REQUIRED for finding a good translation. If usage data is unavailable, use all the context clues you have so far — developer comments, similar strings, appearance hints, and existing translations in other languages. Some UI words are both noun and verb (e.g. "Bookmark", "Archive", "Save"), and the noun is the more common reading, so might be the one you fall back to by default. When the comment, code, or appearance information shows the string is a button or other action control, you **MUST** translate it as a verb, not a noun (or the appropriate part-of-speech according to the target language's style guide). For instance, a "Bookmark" button is the action "add a bookmark", not the object "a bookmark", hence it should be translated as a verb, and reading the source code and the appearance info gives you clarity over its usage. Give both labels of a toggle (e.g. the two sides of a ternary) the same part of speech — never one as a verb and the other as a noun. Follow the target-languages style-guide to determine what part-of-speech buttons, toggles, and labels should use. **Step 3: Gather available style and terminology input, then make style choices** Read and consider guidance from the following: - Explicit guidance in your instructions - Existing translations for the target locale - The locale-specific style guide They cover different concerns, and the higher-priority sources are often incomplete — the lower-priority ones fill the gaps rather than being ignored: 1. **Explicit guidance in your instructions.** Any terminology or style direction in the instructions you were given (how to translate a specific term, the app name, tone guidance, DNT list, etc.) is authoritative — follow it above all else. 2. **Existing translations for the target locale.** Match their terminology, phrasing, register, tone, etc. so the app's translations stay consistent. These reflect choices already made for this project and take precedence over the style guide. 3. **The locale-specific style guide.** Always read `references/styleguide_{locale}.md` (resolve it relative to the skill's base directory) when one exists for the target locale (e.g. `styleguide_pt-BR.md`, `styleguide_zh-Hans.md`—if the file doesn't exist, there isn't a style guide for that locale). Use it to inform your choices when specific guidance doesn't exist in your instructions or existing translations. When these sources conflict, higher-priority items win: explicit instructions override existing translations, which override the style guide. Where none of them settles a question, default to informal/colloquial style. **Step 4: Formulate translation** Consider: - **Terminology**: Match terms used in similar strings. If "Save" is translated as "Speichern" elsewhere, use it consistently. No matter the similar strings, make sure the part of speech of your target string is preserved: a noun sibling ("Bookmarks") is not a precedent for an action button that shares its stem ("Bookmark") — reuse the term, keep the part of speech the usage calls for. - **Tone and formality**: Decide on the style of your translation based on your choices in step 3 - **App names**: Once you decide on how to translate an app name, make sure to to stick to this decision everywhere the app name is referenced. - **Format specifiers**: Understand what each specifier represents by reading the source code (e.g., `%lld` might be a count of items, files, or users). **Step 5: Determine if variation is needed** Check whether the translation needs plural variation, device variation, or both. - **Plural**: If the string contains a numeric format specifier (`%lld`, `%d`, `%u`, etc.) paired with a countable noun, read [references/plural-variations.md](./references/plural-variations.md) (resolve it relative to the skill's base directory). The context tool provides `relevantPluralCases` for your target locale—use all of them. - If the context tool also returned `sourcePluralCasesToAdd`, the source itself isn't plural-varied yet. Vary the source first in a separate `StringCatalogEdit` call before translating the target — [references/plural-variations.md](./references/plural-variations.md) walks through this two-step flow. - **Device**: If the string references a device-specific interaction (tap vs. click) or mentions a device by name, read [references/device-variations.md](./references/device-variations.md) (resolve it relative to the skill's base directory) - **Both**: A string can need both — for example, "Tap to launch %lld spaceships" differs by device AND has a countable noun. Combine device and plural keys (e.g., `device.iphone.plural.one`), but keep `device.other` as a flat fallback string that covers both variations **Step 6: Insert translation** Call `StringCatalogEdit` with the appropriate translation type. Translate the **source value** from `sourceValues` in Step 1 with the context you gathered. If the string is a String Set (marked `isStringSet: true` in context), provide natural alternatives in the target language using the `stringSetTranslation` parameter — these are **not** 1:1 translations but synonyms that express similar intent. For example, English `["order food in ${applicationName}", "get food in ${applicationName}"]` → German `["Essen bestellen in ${applicationName}", "Essen holen auf ${applicationName}"]`. Continue to the next string. **Repeat these 6 steps until all requested strings are translated.** Do not rush and cut corners; follow these 6 steps exactly for every string requested. # Tool Reference ## StringCatalogContext Returns context and the source language value for a given string. The `sourceValues` field contains the text that must be translated. Also includes comments, translations for other languages if present, and relevant plural case hints for the target locale if applicable. Curly apostrophes and quotes are escaped (e.g., \\u2019 for curly apostrophe, \\u201C for curly quote). ### Inputs | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `tabIdentifier` | String | Yes | Workspace tab identifier | | `filePath` | String | Yes | Path to String Catalog | | `stringKey` | String | Yes | String key to get context for | | `targetLocaleIdentifier` | String | Yes | Locale for translation (e.g., `de`, `pt-PT`) | ### Outputs | Field | Type | Description | |-------|------|-------------| | `sourceValues` | SourceValues | The source language values to translate (see SourceValues type below) | | `shouldTranslate` | Bool | Whether string should be translated (false = DO NOT TRANSLATE) | | `isStringSet` | Bool? | Whether this is a String Set (only present when true) | | `comment` | String? | Developer comment from String Catalog | | `relevantPluralCases` | [String]? | Plural cases for target locale (e.g., `["plural.one", "plural.other"]`). Absent when the string doesn't require pluralization. | | `sourcePluralCasesToAdd` | [String]? | Plural cases for the source locale. Present when the source string has a numerical format specifier but is not yet plural-varied. Absent when the source string doesn't require pluralization. | | `translations` | [LocalizationInfo] | All existing translations across non-source locales | | `usageLocations` | [UsageLocation]? | Source code locations where string is used | | `appearances` | [AppearanceInfo]? | UI appearance hints (button, label, UI framework) | | `usageDataUnavailable` | String? | Message when usage data can't be retrieved (e.g., "Build the project...") | | `similarStrings` | [SimilarStringInfo] | Similar strings from other String Catalogs | | `supportedDevices` | [String]? | Devices this app builds for (e.g., `["device.iphone", "device.mac"]`). Only present when the app targets multiple device families. | ### Output Types #### LocalizationInfo The terminology choices for this string in other languages can be an indicator of what terminology to choose for this translation. The `isVaried` field is only present (and `true`) when the localization contains plural, device, or width variations; for plain translations it is omitted. ```json { "localeIdentifier": "de", "value": "Willkommen!" } ``` When the localization is varied, `value` carries a human-readable description of the variation tree: ```json { "localeIdentifier": "he", "value": "plural.one: ...\nplural.other: ...", "isVaried": true } ``` #### UsageLocation Checking how the string is used in source code can provide important context on the terminology to choose (noun vs. verb, etc.) ```json { "fileURL": "file:///path/to/File.swift", "lineNumber": 42, "columnNumber": 15 } ``` #### AppearanceInfo The way this string is presented in UI is a strong signal for part of speech to choose: translate a button or other action control as an action. ```json { "usageHint": "This string is used in a SwiftUI button" } ``` #### SimilarStringInfo Ensure consistent terminology, formality, and style by basing new translations off existing similar strings. ```json { "key": "save_button", "sourceDescription": "Save", "targetDescription": "Speichern" } ``` #### SourceValues The source language values that must be translated. Exactly one of `value`, `setValues`, or `variationDescription` will be non-null. | Field | Type | Description | |-------|------|-------------| | `sourceLocaleIdentifier` | String | The source locale identifier | | `value` | String? | Source text for simple strings | | `setValues` | [String]? | Source values for string sets | | `variationDescription` | String? | Variation tree for varied strings | --- ## StringCatalogEdit Inserts or updates a translation in a String Catalog. Can handle simple strings, varied strings, and String Sets. If the string needs variation (e.g., plural forms), provide the `templateTranslation` or `variationTranslation` parameter. For String Sets (voice assistant commands), use `stringSetTranslation`. Prefer typographically correct quotes for the target language (e.g., „...“ for German, «...» for French). All curly quotes must be escaped (e.g., \\u201E...\\u201C for German „...“). **Critical:** Translations must be in the correct target locale. Refer to your initial instructions to determine which locale applies. Do not infer a locale from examples in this document. ### Inputs | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `tabIdentifier` | String | Yes | Workspace tab identifier | | `filePath` | String | Yes | Path to String Catalog | | `stringKey` | String | Yes | String key to translate | | `targetLocaleIdentifier` | String | Yes | Target locale (e.g., `de`, `pt-PT`) | **Plus exactly one of the following (mutually exclusive):** | Parameter | Type | Description | |-----------|------|-------------| | `translation` | String | Simple string translation (no variations) | | `templateTranslation` | TemplateTranslation | Template with substitutions for multiple plural nouns | | `variationTranslation` | VariationTranslation | Top-level variations (device, width, or single plural noun) | | `stringSetTranslation` | [String] | Array of values for String Sets | ### Translation Types #### Simple Translation For strings without variations: ```json { "stringKey": "welcome_message", "targetLocaleIdentifier": "de", "translation": "Willkommen in unserer App!" } ``` #### Template Translation For strings with multiple format specifiers + countable nouns: ```json { "stringKey": "usage_message", "targetLocaleIdentifier": "de", "templateTranslation": { "template": "iCloud+ wird von %#@arg1@ und %#@arg2@ verwendet.", "substitutions": [ { "name": "arg1", "argNum": 1, "formatSpecifier": "lu", "variants": { "plural.one": "%arg Gerät", "plural.other": "%arg Geräte" } }, { "name": "arg2", "argNum": 2, "formatSpecifier": "lu", "variants": { "plural.one": "%arg Mitglied", "plural.other": "%arg Mitglieder" } } ] } } ``` #### Variation Translation For strings with top-level plural, device, or width variations, or a single format specifier + countable noun: **Single plural noun:** ```json { "stringKey": "item_count", "targetLocaleIdentifier": "pl", "variationTranslation": { "topLevelVariation": { "plural.one": "Masz %lld przedmiot", "plural.few": "Masz %lld przedmioty", "plural.many": "Masz %lld przedmiotów", "plural.other": "Masz %lld przedmiotu" } } } ``` **Device-only variations (no plurals):** ```json { "stringKey": "action_hint", "targetLocaleIdentifier": "es", "variationTranslation": { "topLevelVariation": { "device.iphone": "Toca aquí", "device.mac": "Haz clic aquí", "device.other": "Pulsa aquí" } } } ``` **Device variations with single plural noun:** ```json { "stringKey": "launch_button", "targetLocaleIdentifier": "fr", "variationTranslation": { "topLevelVariation": { "device.iphone.plural.one": "Touchez pour lancer %lld vaisseau spatial", "device.iphone.plural.other": "Touchez pour lancer %lld vaisseaux spatiaux", "device.mac.plural.one": "Cliquez pour lancer %lld vaisseau spatial",
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub