Formats

.stringsdict

Plural forms for a .strings table. Written next to its singulars by the same sync, with one entry per CLDR category the locale has.

What you get

Everything the editor does, through the files you already ship.

  • Every plural form a language has

    Each locale gets exactly the CLDR categories it uses, Arabic six and Japanese one, written in the format's own plural shape.

  • Five checks on every save

    Placeholders, length, terminology, consistency and missing translations are flagged on the row they concern, not in production.

  • Scriptable from the CLI

    Push, pull and sync from a terminal, a build phase or a coding agent's shell, with a token in the environment.

    The CLI
  • Everything is an HTTP call

    Project tokens carry read, push and manage scopes, so a CI token that pushes files cannot delete keys.

    The HTTP API

Set it up

From nothing to every language.

  1. Step 1: Format the count through the dictionary

    Foundation picks the category for the count at runtime. The key holds a format string whose %#@name@ refers to the plural rule, and localizedStringWithFormat fills it in.

    CartViewController.swift
    let format = NSLocalizedString("cart.items", comment: "Items in the cart")
    countLabel.text = String.localizedStringWithFormat(format, cart.count)
  2. Step 2: Install the CLI and log in

    Homebrew or the one-line installer, then a token issued per project under Settings, Integrations. The read scope pulls; push writes source files and values; manage creates and deletes keys.

    shell
    brew install anylocale/tap/anylocale
    anylocale login --project my-app
  3. Step 3: Sync, and the .stringsdict comes along

    A table with at least one plural key gets a .stringsdict beside its .strings file, with one entry per category the locale uses and the value type the source declared.

    shell
    anylocale sync --project my-app --out-dir Sources/Resources
    de.lproj/Localizable.stringsdict
    <?xml version="1.0" encoding="UTF-8"?>
    <plist version="1.0">
      <dict>
        <key>cart.items</key>
        <dict>
          <key>NSStringLocalizedFormatKey</key>
          <string>%#@count@</string>
          <key>count</key>
          <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>one</key>
            <string>1 Artikel</string>
            <key>other</key>
            <string>%d Artikel</string>
          </dict>
        </dict>
      </dict>
    </plist>
  4. Step 4: Write plural values from a script

    Every category the locale has must be supplied at once; a partial set is refused and nothing is written.

    shell
    anylocale values set --project my-app --name cart.items \
        --value de.one="1 Artikel" \
        --value de.other="%d Artikel"

Good to know

  • Which categories exist is decided per locale: German has one and other, Polish adds few and many, Japanese has other only.
  • Keys with several named variables are edited in the app, not through values set.

Questions

Which plural categories does each language get?
Exactly the ones CLDR defines for it: German has one and other, Polish adds few and many, Arabic has six and Japanese only other. The editor shows one field per category, so nothing is guessed.
Can plurals be written from a script?
Yes, with values set, one value per category. Every category the locale has must be supplied in the same call; a partial set is refused and nothing is written.
What about keys with several counted variables?
A key with more than one named variable is edited in the app, where each combination has its own field. The CLI and the device files leave those keys alone.
Which other formats can the same project be pulled in?
.xcstrings, .strings with .stringsdict, strings.xml, JSON, next-intl messages and CSV. A project is not tied to the format it was pushed in, which is how an iOS app and an Android app share one catalog..xcstrings.stringsstrings.xmlJSONnext-intlCSV

Start with the file your app already ships.

After checkout, import one strings file and read the first drafts within minutes.

Nothing to connect and nothing to install. The CLI is optional.