iOS .stringsdict Format Guide (iOS Plurals)
The .stringsdict format is Apple's specialized format for working with plural forms in iOS and macOS applications, providing more powerful capabilities compared to regular .strings files.
What is .stringsdict format
The .stringsdict format is an XML file in Property List (plist) format that allows creating complex rules for plural forms, supporting multiple variables and nested plural expressions.
Key features
-
Complex plural rules — Support for multiple variables in one expression
-
Nested plurals — Nested plural forms within other plural forms
-
Positional arguments — Precise control over variable order
-
Advanced localization — Support for all language plural rules
-
XML structure — Strict typing and validation
File structure and syntax
Basic structure
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict>
<!-- Keys and their definitions --></dict></plist>
Simple plural key
<key>VOICE_MEMO_DURATION</key><dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@text@</string>
<key>text</key>
<dict><key>NSStringFormatSpecTypeKey</key><string>NSStringPluralRuleType</string><key>NSStringFormatValueTypeKey</key><string>d</string><key>one</key><string>Voice message %d second</string><key>other</key><string>Voice message %d seconds</string>
</dict></dict>
Plural key components
-
Main key —
VOICE_MEMO_DURATION
(similar to .strings files) -
NSStringLocalizedFormatKey — Format template
%#@text@
-
Variable —
text
(corresponds to@text@
in template) -
Type specification —
NSStringPluralRuleType
for plural rules -
Value type —
d
for integer,f
for float, etc. -
Plural forms —
one
,other
,few
,many
,zero
,two
Complex examples with multiple variables
Double plural forms
<key>ACCESSIBILITY_LABEL_LONG_VOICE_MEMO_%d_%d</key><dict>
<key>NSStringLocalizedFormatKey</key>
<string>%1$#@minutes@ and %2$#@seconds@</string>
<key>minutes</key>
<dict><key>NSStringFormatSpecTypeKey</key><string>NSStringPluralRuleType</string><key>NSStringFormatValueTypeKey</key><string>d</string><key>one</key><string>%d minute</string><key>other</key><string>%d minutes</string>
</dict>
<key>seconds</key>
<dict><key>NSStringFormatSpecTypeKey</key><string>NSStringPluralRuleType</string><key>NSStringFormatValueTypeKey</key><string>d</string><key>one</key><string>%d second</string><key>other</key><string>%d seconds</string>
</dict></dict>
Nested dependencies
<key>CONVERSATION_SEARCH_RESULTS_%d_%d</key><dict>
<key>NSStringLocalizedFormatKey</key>
<string>%1$#@position@</string>
<key>position</key>
<dict><key>NSStringFormatSpecTypeKey</key><string>NSStringPluralRuleType</string><key>NSStringFormatValueTypeKey</key><string>d</string><key>one</key><string>%d %2$#@total@</string><key>other</key><string>%d %2$#@total@</string>
</dict>
<key>total</key>
<dict><key>NSStringFormatSpecTypeKey</key><string>NSStringPluralRuleType</string><key>NSStringFormatValueTypeKey</key><string>d</string><key>one</key><string>match</string><key>other</key><string>of %d matches</string>
</dict></dict>
Complex expressions
<key>DOG_EATING_MESSAGE</key><dict>
<key>NSStringLocalizedFormatKey</key>
<string>My dog %@ ate %#@carrotsCount@ and %#@applesCount@ today!</string>
<key>carrotsCount</key>
<dict><key>NSStringFormatSpecTypeKey</key><string>NSStringPluralRuleType</string><key>NSStringFormatValueTypeKey</key><string>d</string><key>zero</key><string>no carrots</string><key>one</key><string>%d carrot</string><key>other</key><string>%d carrots</string>
</dict>
<key>applesCount</key>
<dict><key>NSStringFormatSpecTypeKey</key><string>NSStringPluralRuleType</string><key>NSStringFormatValueTypeKey</key><string>d</string><key>zero</key><string>no apples</string><key>one</key><string>%d apple</string><key>other</key><string>%d apples</string>
</dict></dict>
Localit.io integration features
Uploading .stringsdict files
When uploading a .stringsdict file to Localit.io, the system automatically parses the complex structure into separate keys:
Source key:
<key>ACCESSIBILITY_LABEL_LONG_VOICE_MEMO_%d_%d</key>
Creates 3 keys in the system:
-
Main key (string type):
ACCESSIBILITY_LABEL_LONG_VOICE_MEMO_%d_%d Value: "%1$#@minutes@ and %2$#@seconds@"
-
First plural key:
ACCESSIBILITY_LABEL_LONG_VOICE_MEMO_%d_%d->minutes Type: plural
-
Second plural key:
ACCESSIBILITY_LABEL_LONG_VOICE_MEMO_%d_%d->seconds Type: plural
Service symbol "->"
Important: The symbol ->
is a service symbol in Localit.io and indicates that the key is a composite key. This symbol:
-
Is mandatory for correct export to .stringsdict format
-
Indicates relationship between main key and its plural components
-
Preserves structure when exporting back to .stringsdict
Editor interface
In the Localit.io editor, composite .stringsdict keys are displayed as follows:
📁 ACCESSIBILITY_LABEL_LONG_VOICE_MEMO_%d_%d (string)
📄 Value: "%1$#@minutes@ and %2$#@seconds@"
├── 📊 ACCESSIBILITY_LABEL_LONG_VOICE_MEMO_%d_%d->minutes (plural)
│ ├── one: "%d minute"
│ └── other: "%d minutes"
│
└── 📊 ACCESSIBILITY_LABEL_LONG_VOICE_MEMO_%d_%d->seconds (plural)
├── one: "%d second"
└── other: "%d seconds"
Supported plural forms
Standard forms
-
zero — For zero (Arabic, Welsh)
-
one — Singular
-
two — Dual (Slovenian, Arabic)
-
few — Small quantities (Russian: 2-4)
-
many — Large quantities (Russian: 5+)
-
other — Other cases
Custom forms
Some projects may use forms that don't match language standards:
<key>CUSTOM_COUNTER</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>zero</key><string>Nothing</string><key>one</key><string>One item</string><key>other</key><string>%d items</string>
</dict></dict>
Variable types and formatting
Supported types
Type | Description | Placeholder example |
---|---|---|
| Integer |
|
| Float |
|
| String/Object |
|
Positional arguments
<key>COMPLEX_MESSAGE</key><dict>
<key>NSStringLocalizedFormatKey</key>
<string>User %1$@ has %2$#@points@ in %3$#@games@</string>
<!-- Definitions for points and games --></dict>
Explanation:
-
%1$@
— First argument (username) -
%2$#@points@
— Second argument (plural for points) -
%3$#@games@
— Third argument (plural for games)
Export and validation
Automatic assembly
When exporting from Localit.io, the system:
-
Groups keys by main name
-
Assembles composite parts using the
->
symbol -
Creates correct XML structure for .stringsdict
-
Validates syntax and Apple specification compliance
Integrity checking
Automatic checks:
-
Correspondence between main key and composite parts
-
Correct XML structure
-
Placeholder validation in plural forms
-
Required service keys verification
Best practices for .stringsdict
Key naming
Use descriptive names:
✅ Good:
PHOTO_COUNT_%d
MESSAGE_THREAD_PARTICIPANTS_%d_%d
DOWNLOAD_PROGRESS_FILES_%d
❌ Bad:
KEY1_%d
MSG_%d_%d
DL_%d
Translation structuring
Logical grouping:
<!-- Group related plural forms --><key>PHOTO_ALBUM_STATS_%d_%d</key><!-- photos and albums are logically related -->
Variable sequence:
<!-- Maintain logical argument order --><string>%1$#@photos@ in %2$#@albums@</string><!-- photos -> albums (logical order) -->
Working with translators
Provide context:
-
Explain purpose of each variable
-
Show examples with different numbers
-
Specify limitations on text length
-
Document relationships between composite parts
Code comments:
// Usage in Swift codelet message = String.localizedStringWithFormat(
NSLocalizedString("PHOTO_ALBUM_STATS_%d_%d", comment: "Shows count of photos in albums. First %d is photos count, second %d is albums count"),
photoCount,
albumCount
)
Troubleshooting
Common issues
Incorrect key structure:
❌ Missing relationship:
MAIN_KEY
MAIN_KEY_minutes // Wrong
✅ Correct relationship:
MAIN_KEY
MAIN_KEY->minutes // Correct
Variable mismatch:
❌ Incorrect:
<key>NSStringLocalizedFormatKey</key><string>%1$#@photos@ and %2$#@videos@</string><!-- But only photos key is defined, videos is missing --><key>photos</key><dict>
<!-- Definition only for photos --></dict>
✅ Correct:
<key>NSStringLocalizedFormatKey</key><string>%1$#@photos@ and %2$#@videos@</string><!-- Both keys are defined: photos and videos --><key>photos</key><dict>
<!-- Definition for photos --></dict><key>videos</key><dict>
<!-- Definition for videos --></dict>
Incorrect placeholder types:
❌ Type mismatch:
<key>NSStringFormatValueTypeKey</key><string>d</string> <!-- Integer --><key>one</key><string>%f photo</string> <!-- Float placeholder -->
✅ Type match:
<key>NSStringFormatValueTypeKey</key><string>d</string> <!-- Integer --><key>one</key><string>%d photo</string> <!-- Integer placeholder -->
Debugging in Xcode
Loading verification:
// Testing .stringsdict keyslet testString = String.localizedStringWithFormat(
NSLocalizedString("YOUR_KEY", comment: ""),
1, 2, 3
)
print("Result: \(testString)")
File validation:
-
Check XML syntax in Xcode
-
Ensure file is added to bundle
-
Verify correct .lproj structure
Migration and compatibility
From .strings to .stringsdict
Simple plural forms:
// .strings (limited)
"items_%d" = "%d items";
// .stringsdict (full support)
<key>items_count</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>%d item</string>
<key>other</key>
<string>%d items</string>
</dict></dict>
Backward compatibility
-
.stringsdict files supported from iOS 7.0+
-
Fallback to .strings for older iOS versions
-
Automatic format selection by system