Skip to content

Localize iOS permission strings via InfoPlist.strings#134

Open
voicecode-bv wants to merge 1 commit into
NativePHP:mainfrom
voicecode-bv:feat/localized-ios-permissions
Open

Localize iOS permission strings via InfoPlist.strings#134
voicecode-bv wants to merge 1 commit into
NativePHP:mainfrom
voicecode-bv:feat/localized-ios-permissions

Conversation

@voicecode-bv
Copy link
Copy Markdown
Contributor

Summary

iOS shows permission usage descriptions in the system language, but the existing nativephp.permissions config only feeds one set of strings into Info.plist — so prompts appear in whichever language the developer wrote, regardless of the user's device locale.

This PR adds per-locale overrides:

  • New app config key nativephp.permission_localizations
  • New plugin manifest key ios.info_plist_localizations

At compile time, IOSPluginCompiler writes one {locale}.lproj/InfoPlist.strings file per locale inside the synced NativePHP group. Xcode 16's PBXFileSystemSynchronizedRootGroup picks the files up automatically; only knownRegions in the pbxproj needs a small update so the locales ship with the bundle. Info.plist remains the source of truth for the fallback language.

App-level entries win over plugins on key collisions, matching the existing merge rules for flat permissions.

Config example

'permissions' => [
    'NSCameraUsageDescription' => 'To upload a profile photo, we need camera access.',
],

'permission_localizations' => [
    'nl' => [
        'NSCameraUsageDescription' => 'Voor het uploaden van een profielfoto hebben we cameratoegang nodig.',
    ],
    'fr' => [
        'NSCameraUsageDescription' => 'Pour téléverser une photo de profil, nous avons besoin de l\\'accès à la caméra.',
    ],
],

Plugin manifest example

{
  "ios": {
    "info_plist": {
      "NSCameraUsageDescription": "Used to take a profile photo."
    },
    "info_plist_localizations": {
      "nl": {
        "NSCameraUsageDescription": "Gebruikt om een profielfoto te maken."
      }
    }
  }
}

Test plan

  • All existing tests still pass (vendor/bin/pest)
  • New tests in tests/Feature/Plugins/IOSCompilerTest.php:
    • App-level permission_localizations produce the right .lproj/InfoPlist.strings files
    • Plugin localizations merge with app overrides (app wins)
    • Empty config writes no files
    • Quotes / backslashes / newlines are escaped in .strings literals
    • New locales are added to knownRegions in project.pbxproj
    • Re-running compile() is idempotent (no dupes in strings file or knownRegions)
  • Manually verified in a real app build (iOS device on Dutch shows Dutch prompts; switched to English shows the Info.plist fallback)

iOS shows permission usage descriptions in the system language, but the
existing `nativephp.permissions` config only feeds one set of strings into
Info.plist — so prompts appear in whichever language the developer wrote,
regardless of the user's device locale.

This adds `nativephp.permission_localizations` (and the parallel plugin
manifest key `ios.info_plist_localizations`) for per-locale overrides.
At compile time the IOSPluginCompiler writes one .lproj/InfoPlist.strings
file per locale inside the synced NativePHP group, where Xcode 16's
PBXFileSystemSynchronizedRootGroup picks them up automatically; only
`knownRegions` in the pbxproj needs a small update so the locales ship
with the bundle. Info.plist remains the source of truth for the fallback
language.

App-level entries win over plugins on key collisions, matching the
existing merge rules for flat permissions.
Copy link
Copy Markdown
Member

@simonhamp simonhamp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love it! Can you add a PR in the nativephp.com repo for the docs too?

@voicecode-bv
Copy link
Copy Markdown
Contributor Author

Sure thing, there you go: https://github.com/NativePHP/nativephp.com/pull/383/commits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants