From b33a1d37efaf9dff23acc2e4f3cfe64da862f355 Mon Sep 17 00:00:00 2001 From: Michael Blijleven Date: Fri, 15 May 2026 14:40:24 +0200 Subject: [PATCH] Document iOS permission string localizations Adds two sections covering the new `permission_localizations` config key and the matching `ios.info_plist_localizations` plugin manifest key, introduced in NativePHP/mobile-air#134. iOS picks the right string at runtime based on the device language, with `Info.plist` remaining the development-region fallback. --- .../mobile/3/getting-started/configuration.md | 39 +++++++++++++++++++ .../3/plugins/permissions-dependencies.md | 33 ++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/resources/views/docs/mobile/3/getting-started/configuration.md b/resources/views/docs/mobile/3/getting-started/configuration.md index 5cc588c6..cbde8c9c 100644 --- a/resources/views/docs/mobile/3/getting-started/configuration.md +++ b/resources/views/docs/mobile/3/getting-started/configuration.md @@ -332,6 +332,45 @@ are shown at runtime by app code, so there's no equivalent override. +## Localizing iOS Permission Strings + +The strings in `permissions` go straight into `Info.plist`, which iOS treats as the **development region** +fallback. Users running their device in another language see those same strings unless you ship a localized +override. + +Add per-locale strings under `permission_localizations`. Each key is a BCP 47 locale code +(e.g. `nl`, `fr`, `zh-Hans`, `pt-BR`) and its value mirrors the `permissions` shape: + +```php +'permissions' => [ + 'NSCameraUsageDescription' => 'Used to take a profile photo.', +], + +'permission_localizations' => [ + 'nl' => [ + 'NSCameraUsageDescription' => 'Gebruikt om een profielfoto te maken.', + ], + 'fr' => [ + 'NSCameraUsageDescription' => 'Utilisé pour prendre une photo de profil.', + ], +], +``` + +At build time NativePHP writes one `{locale}.lproj/InfoPlist.strings` file per locale inside the iOS bundle +and registers the locale with the Xcode project so it ships with the app. iOS then picks the right string +at runtime based on the user's preferred language, falling back to the value in `permissions`. + + + +Plugins can ship their own per-locale strings — see +[Permissions & Dependencies](../plugins/permissions-dependencies#localizing-info-plist-strings) — and +app-level entries always win on key collisions, same as the merge rules for flat `permissions`. + ## App Store Connect Configure automated iOS uploads with the App Store Connect API: diff --git a/resources/views/docs/mobile/3/plugins/permissions-dependencies.md b/resources/views/docs/mobile/3/plugins/permissions-dependencies.md index 30f0ccea..41d232d4 100644 --- a/resources/views/docs/mobile/3/plugins/permissions-dependencies.md +++ b/resources/views/docs/mobile/3/plugins/permissions-dependencies.md @@ -82,6 +82,39 @@ rejection. Explain *why* you need the permission. +### Localizing Info.plist Strings + +Values in `ios.info_plist` are written to the bundle's `Info.plist` and shown by iOS in whichever language +they were authored. To translate them for users on other system languages, add a sibling +`ios.info_plist_localizations` block. Each key is a BCP 47 locale code (e.g. `nl`, `fr`, `zh-Hans`, +`pt-BR`) and its value mirrors the `info_plist` shape: + +```json +{ + "ios": { + "info_plist": { + "NSCameraUsageDescription": "This app uses the camera for scanning" + }, + "info_plist_localizations": { + "nl": { + "NSCameraUsageDescription": "Deze app gebruikt de camera om te scannen" + }, + "fr": { + "NSCameraUsageDescription": "Cette application utilise la caméra pour le scan" + } + } + } +} +``` + +At build time NativePHP writes one `{locale}.lproj/InfoPlist.strings` file per locale into the host app's +iOS project, and iOS picks the right string at runtime based on the user's preferred language. Any key not +present in a locale block falls back to the value from `info_plist`. + +App-level overrides set in the host app's `config('nativephp.permission_localizations')` win over the values +declared here — useful when an app developer needs to resolve collisions between plugins that ship +localizations for the same key. + ## Dependencies ### Android Dependencies