Localization on macOS and iOS looks very similar. Both platforms share the same concepts, programming language and localization approach. In Swift world, the most commonly used localization format for messages are *.strings files. Each *.strings file contains translated messages and sits in a separate directory, see an example below.
Note: Localizable strings file format has been replaced by Localizable.xcstrings file format

Translations format is straightforward. The first value is a translation key used by a programmer during software development, and the second is a translated message which will be visible for the end user.
File format example
"Access denied!" = "¡Acceso denegado!";
"Accurate to approx. 15 decimal places" = "Accurate to approx. 15 decimal places";
"Accurate to approx. 7 decimal places" = "Accurate to approx. 7 decimal places";
Upload with CLI
simplelocalize upload --apiKey <PROJECT_API_KEY> \
--uploadFormat localizable-strings \
--uploadPath ./{lang}/Localizable.strings
Learn more about SimpleLocalize CLI and translations upload feature.
Download with CLI
simplelocalize download --apiKey <PROJECT_API_KEY> \
--downloadFormat localizable-strings \
--downloadPath ./{lang}/Localizable.strings
Learn more about SimpleLocalize CLI and translations download feature.
Universal placeholders
SimpleLocalize supports universal placeholders that allow you to convert native iOS/macOS format specifiers
(like %@, %lld, %d, %f, %1$@) into a platform-independent format.
This feature is useful when you manage translations for multiple platforms (Android + iOS/macOS) and want
to keep a consistent placeholder format across all of them.
The universal placeholder format uses curly braces {} around the format specifier:
| iOS/macOS native | Universal placeholder | Description |
|---|---|---|
%@ | {%s} | String (object) |
%lld | {%i} | Integer (long long) |
%d | {%i} | Integer |
%f | {%f} | Float |
%1$@ | {%1$s} | Positional string |
%1$lld | {%1$i} | Positional integer |
%.2f | {%.2f} | Float with precision |
%1$.2f | {%1$.2f} | Positional float with precision |
Enabling universal placeholders
To enable universal placeholders, add UNIVERSAL_PLACEHOLDERS to the --uploadOptions or --downloadOptions parameter.
Import (upload) - converts native iOS/macOS placeholders to universal format:
simplelocalize upload --apiKey <PROJECT_API_KEY> \
--uploadFormat localizable-strings \
--uploadPath ./{lang}/Localizable.strings \
--uploadOptions UNIVERSAL_PLACEHOLDERS
Export (download) - converts universal placeholders back to native iOS format:
simplelocalize download --apiKey <PROJECT_API_KEY> \
--downloadFormat localizable-strings \
--downloadPath ./{lang}/Localizable.strings \
--downloadOptions UNIVERSAL_PLACEHOLDERS
Example
Given the following iOS/macOS string:
"welcome_message" = "Hello %1$@, you have %2$lld new messages worth %.2f USD";
After import with UNIVERSAL_PLACEHOLDERS option, the translation in SimpleLocalize will be stored as:
Hello {%1$s}, you have {%2$i} new messages worth {%.2f} USD
During export with UNIVERSAL_PLACEHOLDERS option, it will be converted back to the native Apple format.
If you export to Android Strings format, the same universal placeholders will be converted to the appropriate Android format specifiers.
Import with API
curl
--request POST \
--url 'https://api.simplelocalize.io/api/v2/import?uploadFormat=localizable-strings' \
--header 'x-simplelocalize-token: <API_KEY>' \
--form file=@/path/to/your/Localizable.strings
Learn more about importing translations with API
Export with API
curl
--request GET \
--url https://api.simplelocalize.io/api/v4/export?downloadFormat=localizable-strings \
--header 'x-simplelocalize-token: <API_KEY>'
Learn more about exporting translations with API