This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/ios/features/localization.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Localization: Change languages in iOS PDF viewer | Nutrient

Nutrient iOS SDK comes with many built-in languages:

  • Arabic (ar) (including R2L interface support)
  • Chinese Simplified / Chinese Traditional (zh-Hans/zh-Hant)
  • Croatian (hr)
  • Czech (cs)
  • Danish (da)
  • Dutch (nl)
  • English (en)
  • English United Kingdom (en-GB)
  • Finnish (fi)
  • French (fr)
  • French Canada (fr-CA)
  • German (de)
  • Greek (el)
  • Hebrew (he)
  • Indonesian (id)
  • Italian (it)
  • Japanese (ja)
  • Korean (ko)
  • Malay (ms)
  • Norwegian Bokmål (nb-NO)
  • Polish (pl)
  • Portuguese Brazil / Portugal (pt-BR/pt-PT)
  • Russian (ru)
  • Slovak (sk)
  • Slovenian (sl)
  • Spanish (es)
  • Swedish (sv)
  • Thai (th)
  • Turkish (tr)
  • Ukrainian (uk)
  • Welsh (cy)

These languages are used automatically depending on the preferred language. To enable a language, you must also localize your application in that language. Otherwise, Nutrient iOS SDK falls back to English, since a partially translated app isn’t a good user experience.

To translate your app, follow Apple’s localization guidelines(opens in a new tab) and provide your .strings file in all the languages you want to support.

You can also use Nutrient iOS SDK’s setLocalizationDictionary(_:) or setLocalizationClosure(_:) to customize the localization.

iTunes Connect doesn’t support all of these languages. However, iOS devices can still be set to these languages. Just be aware that there’s no localized storefront. See here(opens in a new tab) for a detailed list of Xcode language codes.

Adding additional localization to Nutrient iOS SDK

You can add additional localization by adding the corresponding folders or setting a new localization programmatically.

To see all strings to localize, look inside PSPDFKit/PSPDFKit.bundle/en.lproj/PSPDFKit.strings. Nutrient iOS SDK uses NSLocale.preferredLanguages to determine a language. It falls back to English if this method doesn’t return anything, or if the language isn’t available in either the PSPDFKit.bundle or the language dictionary. Nutrient iOS SDK won’t look into your default project strings file. To get all strings translated (including OS-level default buttons like Edit or Done), add a Localizable.strings file of your target language to your project:

setLocalizationDictionary([
"en": [
"Go to %@": "Browse %@",
"%d of %d": "Page %d of %d"
]
])

The tool names shown in the annotation toolbar and its long-press menus are localized strings from PSPDFKit.strings. As a result, setLocalizationDictionary(_:) can override them the same way it overrides any other string — per language. For example, the ink pen and ink highlighter tools use the strings Pen and Highlighter.

setLocalizationDictionary([
"en": [
"Pen": "Custom Pen",
"Highlighter": "Custom Highlighter"
],
"ja": [
"Pen": "カスタムペン",
"Highlighter": "カスタム蛍光ペン"
]
])

These overrides apply wherever the same source string is used in Nutrient iOS SDK UI.

Furthermore, you can use setLocalizationClosure(_:) to register a block that’s called every time a string is translated. In this way, you can use your default bundle or a custom bundle with NSLocalizedStringFromTableInBundle:

setLocalizationClosure { stringToLocalize in
guard let stringToLocalize = stringToLocalize else { return nil }
// This will look up strings in `language/PSPDFKit.strings` inside your resource folder.
return NSLocalizedString(stringToLocalize, tableName: "PSPDFKit", comment: "")
// You can also route translation through your default localization:
return NSLocalizedString(stringToLocalize, comment: "")
// Or use a custom variant, for example, to test if everything is localized.
// Keep in mind that several strings, like Edit, are provided by the system and are automatically translated, so long as you have the correct localization resources set.
return String(format: "_____%@_____", arguments: [stringToLocalize])
}

Pluralization considerations

Nutrient iOS SDK uses both the PSPDFKit.strings file and the PSPDFKit.stringsdict file. A .stringsdict file(opens in a new tab) defines language pluralization rules, since some languages have more pluralization variants besides one and many. For example, see the pluralization rule for Croatian:

<key>%tu match(es) found</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@tu_matches_found@</string>
<key>tu_matches_found</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>tu</string>
<key>zero</key>
<string>Nema pronađenih rezultata</string>
<key>one</key>
<string>%tu pronađen rezultat</string>
<key>two</key>
<string>%tu pronađena rezultata</string>
<key>other</key>
<string>%tu pronađenih rezultata</string>
</dict>
</dict>

PSPDFLocalize() automatically looks in both the stringsdict and the classical strings files to look up localized strings.

Forcing a specific language

You can manually override system defaults and force a specific language. We generally don’t recommend this, as it’s against Apple HIG. If you have a use case that requires this, recreate all UI elements manually after updating the setting. Or, ideally, simply restart the application to update the localization. You can achieve this by setting setLocalizationClosure(_:) and returning a custom language, or (better) changing this systemwide via setting the AppleLanguages in the user defaults. This needs to happen early, before your app initializes. You can place this in the main.m/Main.swift file before UIApplicationMain or simply use a function with a constructor attribute in an Objective-C file:

__attribute__((constructor)) static void PSCForceCustomLanguage(void) {
[NSUserDefaults.standardUserDefaults setObject:@[@"de"] forKey:@"AppleLanguages"];
}

See how this can be done in Swift here(opens in a new tab).

You can learn more about AppleLanguages in Apple’s QA1391 article(opens in a new tab). If your app requires updating localization at runtime without restarting the app, you can do more advanced tricks like swizzling NSBundle’s localizedString(forKey:value:table:)(opens in a new tab).