Skip to content

iOS: emit aps-environment entitlement for push notifications (#5074)#5121

Merged
proggeramlug merged 2 commits into
mainfrom
claude/github-issue-5074-v4nkpg
Jun 14, 2026
Merged

iOS: emit aps-environment entitlement for push notifications (#5074)#5121
proggeramlug merged 2 commits into
mainfrom
claude/github-issue-5074-v4nkpg

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #5074.

Problem

registerForRemoteNotifications (notificationRegisterRemote in perry/system) always failed on Perry-built iOS apps. The runtime side was already complete — the registration call plus the didRegister…DeviceToken delegate wiring in perry-ui-ios — but the signed .app never carried the aps-environment entitlement, so iOS responded with didFailToRegisterForRemoteNotificationsWithError and no APNs device token was ever produced. There was no perry.toml key to request it.

Fix

New opt-in switch in perry.toml:

[ios]
push_notifications = true          # emit the aps-environment entitlement
# push_environment = "production"  # default "development"; set for distribution
  • Compileinject_ios_push_entitlement (apple_info_plist.rs) writes aps-environment into the bundle's app.entitlements during perry compile --target ios. Defaults to development (matching the dev-signed bundles compile produces); push_environment = "production" overrides it for App Store / Ad Hoc distribution, and any other value clamps back to development. Idempotent with the deeplinks (Deep links: Universal Links (iOS) + App Links (Android) + URL-scheme open handling #583) and App Group (appGroupSet/Get/Delete on iOS is an in-process HashMap stub — wire UserDefaults(suiteName:) (follow-up to #675) #1178) entitlement passes — splices the key into an existing app.entitlements rather than clobbering it, and leaves a hand-written aps-environment alone.
  • Dev resignbuild_dev_entitlements_xml already layers the development signing keys on top of the compile-emitted app.entitlements, so the push entitlement survives perry run --target ios re-signing (new regression test).
  • Provisioningcreate_dev_profile_via_api now enables the PUSH_NOTIFICATIONS capability on the App ID (best-effort, mirroring the App Groups toggle) when [ios] push_notifications = true. Wired through both perry setup ios and perry run --target ios.

Docs / tests

  • docs/src/system/notifications.md gains an "Enabling APNs on iOS" section.
  • 8 new unit tests across apple_info_plist.rs and resign.rs; full perry suite green (543 passed), release build succeeds.

Note: no version bump / CHANGELOG entry in this branch — left for the maintainer to fold in at merge time.

https://claude.ai/code/session_017TRpeWZrkdbBwpmGQb7eXE


Generated by Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added iOS push notifications support: configure push_notifications = true in project configuration to enable APNs.
    • Automatic injection of push notification entitlements during app compilation.
    • Automatic App Store Connect capability enablement during development setup.
  • Documentation

    • Added guide for configuring and enabling iOS push notifications.

registerForRemoteNotifications always failed on Perry-built iOS apps
because the signed .app never carried the aps-environment entitlement,
so iOS responded with didFailToRegisterForRemoteNotificationsWithError
and no APNs device token was produced. The runtime side was already
complete; the only gap was the entitlement.

Add an opt-in perry.toml switch:

  [ios]
  push_notifications = true          # emit aps-environment
  # push_environment = "production"  # default "development"

- inject_ios_push_entitlement writes aps-environment into the bundle's
  app.entitlements during `perry compile --target ios`, defaulting to
  development and clamping unknown push_environment values back to it.
  Idempotent with the deeplinks (#583) and App Group (#1178) passes.
- build_dev_entitlements_xml already layers dev signing keys on top of
  the compile-emitted entitlements, so push survives `perry run` resign
  (new regression test).
- create_dev_profile_via_api enables the PUSH_NOTIFICATIONS capability on
  the App ID (best-effort, mirroring App Groups) when opted in; wired
  through both `perry setup ios` and `perry run --target ios`.

Docs: notifications.md gains an "Enabling APNs on iOS" section.
Tests: 8 new unit tests across apple_info_plist.rs and resign.rs.

https://claude.ai/code/session_017TRpeWZrkdbBwpmGQb7eXE
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 948640ef-319c-4c14-a6dd-5f0e0f19c38b

📥 Commits

Reviewing files that changed from the base of the PR and between c970fc5 and bc52e27.

📒 Files selected for processing (6)
  • crates/perry/src/commands/compile/apple_info_plist.rs
  • crates/perry/src/commands/compile/bundle_ios.rs
  • crates/perry/src/commands/run/mod.rs
  • crates/perry/src/commands/run/resign.rs
  • crates/perry/src/commands/setup/ios.rs
  • docs/src/system/notifications.md

📝 Walkthrough

Walkthrough

Adds end-to-end iOS push notification support controlled by [ios] push_notifications = true in perry.toml. During perry compile --target ios, inject_ios_push_entitlement idempotently writes or splices the aps-environment entitlement into app.entitlements. During perry setup ios / perry run, create_dev_profile_via_api gains a push_notifications parameter and calls App Store Connect to enable the PUSH_NOTIFICATIONS capability on the App ID. Documentation for the new flag is added to notifications.md.

Changes

iOS Push Notification Entitlement Pipeline

Layer / File(s) Summary
Compile-time aps-environment injection
crates/perry/src/commands/compile/apple_info_plist.rs, crates/perry/src/commands/compile/bundle_ios.rs
Introduces read_ios_push_config/parse_ios_push_config helpers that walk up to perry.toml and normalize push_environment. inject_ios_push_entitlement idempotently creates or splices aps-environment into app.entitlements (full wrapper when absent, plist splice when key is missing, no-op when key already exists). Wired into the iOS bundle build after existing entitlement passes. Tests cover defaulting, clamping, full creation, splicing, idempotency, and opt-out.
Provisioning push capability toggle and TOML reader
crates/perry/src/commands/run/resign.rs, crates/perry/src/commands/run/mod.rs, crates/perry/src/commands/setup/ios.rs
Adds read_ios_push_notifications_from_toml/parse_ios_push_notifications. Extends create_dev_profile_via_api with a push_notifications: bool parameter; when true, performs a best-effort App Store Connect API call to enable PUSH_NOTIFICATIONS on the App ID (HTTP 409 treated as already-enabled success). resign_for_development and ios_development_setup both read the flag from perry.toml and forward it. Tests cover build_dev_entitlements_xml preservation and TOML parse behavior.
APNs push notifications documentation
docs/src/system/notifications.md
New iOS/APNs subsection describing the perry.toml ios.push_notifications flag, aps-environment entitlement emission during compile, and perry setup ios / perry run capability provisioning for development vs. production.

Sequence Diagram

sequenceDiagram
  participant Developer
  participant perry_compile as perry compile --target ios
  participant inject_ios_push_entitlement
  participant perry_setup as perry setup ios
  participant create_dev_profile_via_api
  participant AppStoreConnect as App Store Connect API

  rect rgba(99, 179, 237, 0.5)
    Note over Developer, inject_ios_push_entitlement: Build path
    Developer->>perry_compile: perry.toml [ios] push_notifications=true
    perry_compile->>inject_ios_push_entitlement: input path, app_dir, format
    inject_ios_push_entitlement->>inject_ios_push_entitlement: read_ios_push_config → (enabled, environment)
    inject_ios_push_entitlement->>inject_ios_push_entitlement: idempotent splice/create app.entitlements
  end

  rect rgba(154, 230, 180, 0.5)
    Note over Developer, AppStoreConnect: Provisioning path
    Developer->>perry_setup: perry.toml [ios] push_notifications=true
    perry_setup->>create_dev_profile_via_api: push_notifications=true
    create_dev_profile_via_api->>AppStoreConnect: enable PUSH_NOTIFICATIONS capability on App ID
    AppStoreConnect-->>create_dev_profile_via_api: 200 OK or 409 (already enabled)
    create_dev_profile_via_api->>create_dev_profile_via_api: mint provisioning profile
    create_dev_profile_via_api-->>perry_setup: profile bytes
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 Hoppity-hop, a token at last!
aps-environment inked in the past
was missing — now Perry writes it with care,
development, production, the plist is there.
Push notifications shall finally ring,
the rabbit has fixed this long-blocked thing! 🔔

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding iOS push notification entitlement support through the aps-environment entitlement, directly addressing issue #5074.
Description check ✅ Passed The PR description provides a clear problem statement, comprehensive explanation of the fix across compile/resign/provisioning stages, documentation and test coverage details, and correctly notes no version bump per maintainer policy.
Linked Issues check ✅ Passed All requirements from issue #5074 are fully addressed: new perry.toml switch [ios] push_notifications=true, aps-environment entitlement emission during compile with development/production variants, and Push Notifications capability automation in provisioning.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to issue #5074: apple_info_plist.rs (entitlement injection), bundle_ios.rs (integration), resign.rs (provisioning), setup/ios.rs (setup flow), and documentation—no extraneous modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/github-issue-5074-v4nkpg

Comment @coderabbitai help to get the list of available commands and usage tips.

@proggeramlug proggeramlug merged commit 3c0fe15 into main Jun 14, 2026
15 checks passed
@proggeramlug proggeramlug deleted the claude/github-issue-5074-v4nkpg branch June 14, 2026 12:45
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.

iOS: no way to emit aps-environment entitlement → registerForRemoteNotifications always fails (push undeliverable)

2 participants