technical-implementation

Pushlane: iOS Push for Subscription Apps

Connect APNs, Pushlane and RevenueCat for an iOS subscription app, from permission and device identity to lifecycle flows and real-device verification.

An iOS subscription push system has three identities that are easy to confuse: the APNs device token, the account ID in your app, and the RevenueCat App User ID. The token tells Apple where to deliver. The account ID tells Pushlane who owns that device. The RevenueCat ID tells the webhook which subscriber changed state.

The implementation works when those responsibilities stay separate and the two user IDs are the same stable value. This guide connects the complete path: iOS permission, APNs registration, Pushlane identity, RevenueCat lifecycle events and a real-device test.

Map the path before adding code

The delivery path is:

iOS app -> APNs device token -> Pushlane registration
RevenueCat webhook -> stable App User ID -> Pushlane flow
Pushlane sender -> APNs -> registered iOS app

Apple describes a device token as an address unique to an app and device. Its official APNs registration guide says the app should request a current token and forward it to its provider server. The token is not a durable customer ID and can change.

RevenueCat recommends a non-guessable custom App User ID when your app has accounts. Its identity documentation also explains aliases and anonymous identities. Pushlane's identify() uses the stable account ID to join devices and events.

The invariant is simple:

let uid = Pushlane.identifyForRevenueCat(currentUser.id)
Purchases.configure(withAPIKey: "appl_...", appUserID: uid)

Do not use an email address, APNs token or random value generated independently by each SDK. On logout, detach the Pushlane identity so a shared device does not continue receiving notifications for the previous account.

Enable the iOS capabilities

In the Xcode app target, add the Push Notifications capability. Enable the notification modes your implementation truly needs. Apple requires the app's signing entitlement to match the App ID configuration; without it, registration fails before Pushlane is involved.

Install the Pushlane iOS SDK through Swift Package Manager using the current iOS quickstart. Add PushlaneCore and PushlanePush to the app target. Configure the SDK with the tenant ID, ingest URL and publishable lpk_... key from the dashboard.

The publishable write key identifies the app for event and device registration. It is not an APNs credential and it must not authenticate RevenueCat webhooks.

If you use rich images or delivery callbacks, follow the Notification Service Extension steps in the quickstart. Start with plain notifications first. A basic notification proves identity and APNs routing with fewer moving parts.

Request permission after the value is understandable

iOS requires authorization for alerts, sounds and badges. Apple's permission guide recommends asking in context, after the person can understand the benefit, instead of automatically prompting on first launch.

For a subscription app, good moments are connected to a real job:

  • after a user schedules a workout and can opt into a reminder;
  • after a budget is connected and the app can explain a relevant alert;
  • after a lesson time is selected;
  • after the person chooses to follow a report or goal.

Do not time the system prompt merely because the paywall closed. Explain the notification the person will receive, then call the system prompt only after affirmative intent. The first explicit system request records the response, and repeating the API call does not display the prompt again.

Keep an in-app notification settings page. People can change iOS settings later, and Apple recommends checking current authorization status rather than relying on the original answer.

Register the current APNs token

After authorization and identity are ready, register for remote notifications. The Pushlane SDK forwards the device token with the user's external ID and the detected APNs environment.

Apple explicitly advises apps not to cache a token as though it never changes. Ask the system for the current token at launch and forward the token your delegate receives. Pushlane handles server-side deduplication, so re-registering the current token is safer than keeping a stale address.

Treat registration failure as observable. Common causes include missing entitlements, an unavailable APNs connection, a simulator-only test or signing against the wrong profile. Do not mark the integration complete merely because the permission dialog appeared.

One account can have multiple Apple devices, and one device can change accounts. Model that honestly. The account ID groups installations; APNs still addresses each installation separately.

Upload the correct APNs key

Pushlane needs an APNs authentication key created in Apple Developer under Certificates, Identifiers & Profiles, not an App Store Connect API key.

Upload these values in Pushlane Settings:

  • the .p8 APNs auth key;
  • its Key ID;
  • the Apple Developer Team ID;
  • the exact app Bundle ID.

The Pushlane APNs setup guide walks through the portal fields. Apple allows the .p8 key to be downloaded once, so store the source securely and rotate deliberately.

A wrong Team ID, Key ID or Bundle ID can produce a provider-token or topic error even when the app registered a valid device token. Verify credentials with a real test push before introducing RevenueCat.

Prove plain delivery first

Use a physical iPhone with a development or TestFlight build. The iOS simulator is not a substitute for proving your production signing, environment and token path.

Run this sequence:

  1. Configure Pushlane.
  2. Identify one test account.
  3. Request permission in the intended product context.
  4. Register the APNs token.
  5. Upload the matching APNs credential set.
  6. Send a Pushlane test notification.
  7. Confirm Apple accepted it and the device displayed it.

Test with the app in foreground, background and terminated states. A foreground app may handle presentation differently, so a successful background test does not prove the foreground delegate behavior.

Pushlane's iOS path is proven end to end through APNs. It records honest suppressions when no active APNs device or valid tenant credential exists instead of calling that outcome sent.

Add RevenueCat only after delivery works

In Pushlane Settings, generate a dedicated rcw_... RevenueCat webhook secret. Add the Pushlane webhook URL and secret as the Authorization value in RevenueCat. RevenueCat's webhook documentation explains delivery, retries and sandbox testing.

The webhook App User ID must equal the Pushlane external ID. If the webhook is accepted but no identified user owns the device, the flow cannot deliver to the intended person. The detailed failure model is in matching RevenueCat App User IDs to APNs tokens.

Send a RevenueCat dashboard test event to verify authentication. Then make a sandbox purchase with the identified test account. Only the sandbox lifecycle proves that the right event, properties and user appear in Pushlane.

Use is_production as the first branch in any customer-facing flow because sandbox subscription events can enter the flow engine.

Choose lifecycle triggers that match the message

Build one flow at a time:

Subscription statePushlane eventMessage job
Paid purchaserevenuecat.initial_purchaseLead to first premium value
Trial activeObserved trial-start eventHelp the person activate and disclose the deadline
Payment failedrevenuecat.billing_issueOffer a correct payment-management path
Auto-renew changedrevenuecat.cancellationAcknowledge current access without claiming expiration
Access endedrevenuecat.expirationInvite a genuinely lapsed user back

RevenueCat's event reference states that BILLING_ISSUE is not expiration and that CANCELLATION can precede the actual end of access. Keep those flows separate. Use RevenueCat push automation blueprints for their exits and handoffs.

Product behavior belongs in Pushlane events sent by the app. Subscription state belongs in RevenueCat webhooks. Do not emit a client event that claims a purchase occurred. A compromised or stale client is not the source of truth for billing.

Test the joins and the stop events

A complete integration test covers more than one successful notification:

  1. Sign in as user A, register a token and verify a push.
  2. Trigger a RevenueCat sandbox event for exactly user A.
  3. Confirm the event enters the expected flow once.
  4. Trigger the stop event during a delay and confirm the pending push is cancelled.
  5. Log out, sign in as user B and ensure the device no longer receives user A's lifecycle messages.
  6. Reinstall or refresh the token and confirm the new registration works.
  7. Deny notification permission and verify the outcome is a suppression, not a delivery.
  8. Use an invalid deep link in a staging flow and prove your tests catch it before production.

Inspect events by user ID, not by the name of the test device. The user ID is the join shared by the two systems.

Measure product and subscription outcomes separately

APNs acceptance, notification interaction, product activation and subscription change answer different questions.

  • APNs acceptance proves transport reached Apple.
  • A tap shows interaction with a notification action.
  • A product event shows the destination helped the person do something.
  • A RevenueCat event shows subscription state changed.

Do not collapse these into one conversion rate or attribute every later renewal to the push. For trial onboarding, report activation and paid conversion separately. For billing recovery, report a verified renewal after the issue and compare against an eligible holdout when volume supports it.

Ship a narrow golden path

The first reliable iOS subscription flow can be one device, one stable user ID, one RevenueCat sandbox event, one plain push and one verified stop event. That narrow path proves every boundary that matters.

Once it works, add localization, audiences, rich media and experiments. If the core identity or APNs credential is wrong, those layers only make the failure harder to diagnose.

Pushlane: iOS Push for Subscription Apps