Neatbo.

XCstrings manual translation exchange

Export existing direct translations and states for collaborators, then apply a complete returned table or a SHA-bound partial patch while retaining untouched catalog bytes.

Browser-local processingInputXCstrings 1.0 / 1.3 + JSONOutputXCstrings / JSONUp to 16 MiB per file · File limit: 2
  1. 1Add input
  2. 2Adjust settings
  3. 3Get your result

Tool input and files are processed in this browser without being uploaded.

Your input

Inputs are kept temporarily in this tab when switching tools. Refreshing or closing clears them; large results may need to be regenerated.

⌘ / Ctrl + Enter to run

Choose the exact original catalog, up to 5 MiB. Its contents stay in this browser.

No file selected

Preparing the tool…

Before you start

Export existing direct translations and states for collaborators, then apply a complete returned table or a SHA-bound partial patch while retaining untouched catalog bytes.

How to use this tool

  1. Choose Export table and select the original catalog.
  2. Send manual-exchange.json to collaborators. Edit only value and state in a JSON editor, keeping the protected fields and every row.
  3. Choose Apply complete table, select the same byte-exact original and the entire returned JSON; or choose Apply partial patch and supply explicit before values.
  4. Review counts and the full change report, download the updated catalog, then validate it in the receiving Xcode project.

Supported inputs and limits

Select one strict UTF-8 XCstrings 1.0 or 1.3 original, at most 5 MiB, without BOM. Import also requires one returned JSON File: a full table up to 16 MiB or an explicit partial patch up to 5 MiB. Two file roles and all options, sizes and scalar Unicode names up to 512 UTF-8 bytes are checked before any complete read.

Export every existing direct stringUnit value and state. Supported states are new, needs_review and translated. Locale names are opaque fixed keys; this does not certify their validity in Xcode. Empty entries/localizations may be retained, but new locales or units are not created.

In the complete returned table, edit only value and state. Preserve format, sourceSha256, version, sourceLanguage, columns, every row, row order, valuePath and sourceLocale. A partial patch uses explicit valuePath, originalValue, originalState, value and state for each edit; unknown or repeated paths and before-value conflicts reject the whole import.

Any variations or substitutions at root, entry, localization or unit scope, unknown state, or unknown localization shape refuse the whole operation. The failed screen retains byte-exact original.xcstrings and the complete unsupported-shapes.json with whole-file copy/download. A fatal structural prerequisite has a separate non-exhaustive diagnosis; it is never presented as a successful updated catalog.

At most 10,000 entries, 50,000 localization records, 50,000 direct units, 64 JSON container levels and 1,000,000 JSON tree nodes. The mature scanner counts containers/literals plus property nodes before recursive parsing; key strings count too. Duplicate keys, malformed JSON, invalid UTF-8 or escaped lone surrogates fail atomically.

Each complete exchange or updated catalog is at most 16 MiB. The complete import change report has a derived 40 MiB capacity; all artifact bytes together are capped at 61 MiB. Failed artifacts stay within 5 MiB original plus 16 MiB diagnosis. No output is silently shortened to fit.

Outside selected value/state string tokens, the original UTF-8 bytes remain exact: comments stored as metadata, spacing, CRLF, unknown objects, fractional numbers and unsafe-integer numeric lexemes are retained. The original download is never a JSON reserialization.

A host deadline of 10 seconds includes File reads, Worker loading, readiness, calculation and complete result validation. Cancel settles immediately and terminates any live Worker; late reads/replies are ignored. Rerun the same original Files and options after stopping. Previews show at most 4,000 Unicode code points; copy/download retain every byte of each complete artifact.

Worked example

Example input

{
  "sourceLanguage": "en",
  "strings": {
    "Greeting": {
      "localizations": {
        "en": {"stringUnit": {"state": "translated", "value": "Hello"}},
        "fr": {"stringUnit": {"state": "needs_review", "value": "Bonjour"}}
      }
    }
  },
  "version": "1.3",
  "opaqueRevision": 9007199254740993,
  "opaqueFraction": 0.125
}
Example options
{"mode":"export"}

Example output

{"format":"neatbo-xcstrings-manual-exchange-v1","sourceSha256":"b891764f343f28dec3340d0b75dab2590ba5bcf08b6ac81cab9330b473cb0d11","version":"1.3","sourceLanguage":"en","columns":["valuePath","value","state","sourceLocale"],"rows":[["/strings/Greeting/localizations/en/stringUnit/value","Hello","translated",true],["/strings/Greeting/localizations/fr/stringUnit/value","Bonjour","needs_review",false]]}

When something does not work

Keep the original and the complete refusal diagnosis. Use a catalog-aware editor for variants, fix binding/grammar errors, or split inputs over the limits. Cancel or timeout leaves the selected Files available for a complete rerun.

Frequently asked questions

Can collaborators edit the source-language row?

Yes: value and state may change in any existing direct unit. sourceLocale is a protected flag describing the original, not an instruction to create or validate a locale.

Can I use a reformatted copy of the original for import?

No. SHA-256 binds the raw original bytes, including whitespace and CRLF. Export a new table after any source change; the returned table must preserve row order and protected fields.

Does this certify Xcode compatibility?

The declared direct-unit profile was checked against retained Xcode producer/consumer evidence. Locale names and receiving-project requirements still need validation in that project; variants are rejected atomically.

Documentation & further reading

Related tools