How to Add Push Notifications to a Median (GoNative) iOS App

A practical walkthrough for enabling native iOS push notifications in a Median (formerly GoNative) web-to-native app, including APNs setup and the JavaScript bridge.

Why Push Notifications Matter for a Wrapper App

Push notifications are one of the clearest examples of native functionality a mobile website cannot deliver on iOS in the same way an app can. That makes them doubly valuable for a Median app.

First, they drive re-engagement and give users a reason to keep the app installed. A well-timed notification brings someone back without any marketing spend.

Second, they are exactly the kind of native capability that helps satisfy Apple's minimum functionality expectations. They demonstrate that the app does something the website alone cannot.

If you are wrapping a site with Median and worried about looking like a thin wrapper, push is often the single highest-impact native feature to add.

The setup involves several moving parts, but the payoff is a concrete, reviewer-visible reason your product deserves to be an app.

How Push Works on iOS

On iOS, all push notifications flow through Apple Push Notification service, or APNs. Your app registers with APNs, receives a device token, and a server uses that token plus an APNs credential to deliver messages.

Median abstracts much of this, typically integrating with a push provider so you can send notifications without writing native APNs code yourself. You still must supply the correct Apple credentials, because only Apple can authorize delivery to its devices.

Think of the flow as a chain: your web app requests permission, the device registers and gets a token, your backend stores that token, and your sender uses it with a valid credential to reach APNs.

Understanding this chain matters for debugging. If notifications fail, the problem is almost always in registration, credentials, or permissions rather than in your web code.

Because the chain is finite and well-defined, methodically checking each link is far more effective than guessing.

Step 1: Enable Push Capability in Your Apple Developer Account

In the Apple Developer portal, make sure your App ID has the Push Notifications capability enabled. This is tied to your bundle identifier, so it must match the identifier configured in Median.

Create an APNs authentication key or the appropriate push certificate as required by your setup. An APNs auth key, delivered as a .p8 file, is the modern approach and works across your apps under one team.

The auth key has practical advantages over legacy certificates. It generally does not expire the way certificates do, which removes a recurring maintenance chore and a common cause of sudden failures.

Keep these credentials secure. The APNs key in particular grants the ability to send to your apps, so treat it like a secret and store it somewhere controlled.

Download the key when you create it, because Apple only lets you download the .p8 file once. Losing it means generating a new one.

Step 2: Configure Push in the Median Dashboard

In Median, enable the push notifications feature for your app and provide the Apple credentials it requests. Median's documentation specifies exactly which files and identifiers to upload, so follow the current instructions at median.co closely.

When you upload an auth key, you generally also provide your Apple Team ID and the key ID so the system can address APNs correctly. Get these values from your developer account.

Confirm your bundle identifier is consistent everywhere: Apple Developer portal, App Store Connect, and Median. A mismatch here is one of the most common reasons push silently fails.

Save the configuration and rebuild the app so the push entitlement is included in the binary. Enabling push in the dashboard has no effect until you produce a new build with the entitlement baked in.

Double-check the rebuilt binary actually carries the push capability before testing, so you are not debugging a build that never had it.

Step 3: Request Notification Permission

iOS requires explicit user permission before an app can show notifications. When the app requests it, the user sees the system prompt to allow or deny.

Time this request thoughtfully. Prompting immediately on first launch often leads to denials, so consider triggering it after the user sees value, using Median's JavaScript bridge to invoke the native permission request at the right moment.

A common pattern is a short in-app explanation before the system prompt, so the user understands why notifications help. This soft-ask improves opt-in rates.

If a user denies permission, iOS will not show that prompt again automatically. They must re-enable notifications in Settings, so your first ask matters.

Because the first request is effectively your only clean shot, treat its timing and framing as a real product decision, not an afterthought.

Step 4: Capture the Device Token and Register Users

Once permission is granted, the device receives a push token. To send targeted notifications, you generally need to associate that token with a user in your own system.

Median exposes the token and registration events through its JavaScript bridge, so your web app can read the token and post it to your backend along with the user's identity.

Store that association server-side and keep it current. Tokens can change, so update your stored value whenever the app reports a new one to avoid sending to a dead token.

This association is what enables per-user messaging — order updates, replies, reminders — rather than only broadcast messages to everyone.

Log the registration event during development so you can confirm the token actually reached your backend. A missing token is a silent failure that is easy to overlook.

Step 5: Send and Test Notifications

Use Median's push sending interface or connected provider to send a test notification to your own device. Confirm it arrives in the foreground, the background, and when the app is fully closed, since iOS handles each state differently.

Each app state has distinct behavior worth verifying. A notification that appears in the background may be handled differently when the app is active and in the foreground.

Test what happens when the user taps the notification. A good implementation deep-links into the relevant screen, which you can wire through the bridge to navigate your web app to a specific URL.

Always test on a real device. The iOS Simulator has limited and version-dependent push support, so a physical iPhone is the reliable way to validate the full flow.

Send a few different payload types too — plain text, and one that carries a deep-link target — so you know your tap handling behaves for the messages you actually plan to send.

Step 6: Handle Common Pitfalls Proactively

Two configuration mistakes cause most failures: a bundle identifier mismatch and an expired or wrong-environment APNs credential. Verify both before assuming anything is broken in code.

Remember the sandbox versus production distinction. Development builds use the APNs sandbox and production App Store builds use production APNs, and a token from one environment will not work against the other.

TestFlight builds behave as production for push purposes, which surprises people who assume test builds always use the sandbox. Match your send environment to the exact build you are testing.

Document your setup so teammates can reproduce it. Push problems are frustrating precisely because the failure is silent, so a clear checklist saves hours later.

Keep that checklist alongside your credentials and identifiers. When something breaks months later during a renewal or environment change, a written baseline is the fastest path back to a working state.

Frequently Asked Questions

Do Median push notifications use APNs?

Yes. All iOS push notifications go through Apple Push Notification service. Median integrates with APNs and typically a push provider so you do not have to write native APNs code, but you must supply valid Apple credentials.

Can I test push on the iOS Simulator?

Simulator push support is limited and version-dependent, so test on a real device. A physical iPhone is the reliable way to validate registration, delivery, and tap handling across app states.

Why did my device not receive a notification?

The most common causes are a bundle identifier mismatch, an expired or wrong-environment APNs credential, denied notification permission, or using a sandbox token against production APNs. Check those before debugging code.

How do I send notifications to specific users?

Capture the device token through Median's JavaScript bridge, send it to your backend with the user's identity, and target that token when sending. Broadcast messages do not require this, but per-user messaging does.