Set up push on iOS
How to make an APNs .p8 key, find the Key ID, Team ID and bundle id, turn on push in Xcode, get the device token and send a first push.
This guide takes an iOS app from no push to a notification on your own iPhone. You need a paid Apple Developer Program membership, Xcode, a real iPhone and your SignOps test key. It takes about 30 minutes.
First, pick a route
iOS pushes can reach Apple in two ways. Pick one in the dashboard under Push, Setup, iOS.
| Straight to Apple (APNs) | Through Firebase | |
|---|---|---|
| Pick it when | Your iOS app does not use Firebase | Your iOS app already uses Firebase Messaging |
| SignOps needs | Your .p8 key, Key ID, Team ID and bundle id |
Your Firebase service account (the one for Android) |
| The app sends | Its APNs device token | Its FCM token |
| Live Activities | Yes | No: they need the .p8 key in SignOps |
Both start with the same Apple key. The steps below are for Straight to Apple; the Firebase route differs only in step 4.
1. Make an APNs key (.p8)
- Sign in at developer.apple.com/account and open Certificates, Identifiers and Profiles, then Keys.
- Choose + (Create a key). Give it a name such as
SignOps push. - Tick Apple Push Notifications service (APNs). If Apple asks you to configure it, choose the environment Sandbox and Production, and a key for your whole team rather than one topic, so the same key works for every build and app.
- Choose Continue, then Register.
- Choose Download. You get a file named
AuthKey_8K2Q9XW4LM.p8. Apple lets you download it once, so keep it somewhere safe, such as your password manager. - Note the Key ID on that page: the 10 characters after
AuthKey_in the file name.
Apple limits how many APNs keys a team can have. If your team already has one (for Firebase or another provider), you can reuse its .p8 file instead of making another.
2. Find your Team ID and bundle id
- Team ID: developer.apple.com/account, Membership details. Ten characters, such as
5HD3K7P2TQ. - Bundle id: in Xcode, select your app target, General, Bundle Identifier, such as
com.kiranaexpress.app. It must match the app exactly; it is the topic Apple delivers to.
3. Upload the key to SignOps
- In the SignOps dashboard, open Push, Setup, choose Set up on iOS, then Straight to Apple (APNs).
- Choose the
.p8file. The Key ID fills itself from the file name. - Type the Team ID and Bundle ID.
- Leave Environment on Production and sandbox.
- Choose Save key. SignOps encrypts it with AES-256-GCM and never shows it again.
4. Turn on push in Xcode
- Select your app target, Signing and Capabilities, choose + Capability and add Push Notifications. With automatic signing, Xcode turns push on for your App ID.
- Add Background Modes and tick Remote notifications if you send silent pushes (pushes with
dataand no title).
5. Ask for permission and get the device token
import UIKit
import UserNotifications
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
// Call this after sign-in, at a moment the user understands
func askForPush() {
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
guard granted else { return }
DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() }
}
}
func application(_ app: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken token: Data) {
let hex = token.map { String(format: "%02x", $0) }.joined()
api.saveDevice(hex) // your own endpoint, with the signed-in user
}
func application(_ app: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("No push token:", error) // usually the Push Notifications capability is missing
}
// Show pushes while the app is open too
func userNotificationCenter(_ c: UNUserNotificationCenter, willPresent n: UNNotification) async -> UNNotificationPresentationOptions {
[.banner, .sound, .badge]
}
}
In a SwiftUI app, attach it with @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate. Call registerForRemoteNotifications() at every launch: the token can change, and adding it again is safe.
Through Firebase instead: upload the same .p8 to the Firebase console (Project settings, Cloud Messaging, Apple app configuration), then send the FCM token from Messaging.messaging().token instead of the hex device token. SignOps does not need the .p8 on this route.
6. Add the token on your server
curl https://api.signops.dev/v1/devices \
-H "Authorization: Bearer $SIGNOPS_KEY" \
-d user_id=usr_8f21c4 -d platform=ios -d token=$APNS_TOKEN
Keep the returned id and remove it with DELETE /v1/devices/:id when the user signs out on that phone. Test and live keys keep separate device lists: a token added with the test key gets pushes sent with the test key.
7. Send a test
Run the app on your iPhone from Xcode, allow notifications, and lock the phone. Then, in the iOS panel, type the user id under Send a test, or from your server:
curl https://api.signops.dev/v1/push \
-H "Authorization: Bearer $SIGNOPS_KEY" \
-H "content-type: application/json" \
-d '{"user_id":"usr_8f21c4","title":"Your order is out for delivery","body":"Ravi is 10 minutes away.","sound":"default","badge":1}'
See what Apple said in the panel shows Apple’s answer for each device.
When something goes wrong
| Apple’s answer | What it means |
|---|---|
BadDeviceToken |
A sandbox token sent to production or the other way round. Set Environment to Production and sandbox |
DeviceTokenNotForTopic |
The bundle id in SignOps is not the app’s bundle id |
InvalidProviderToken |
The Key ID or Team ID does not match the .p8 file, or the key was revoked |
Unregistered |
The app was removed from the phone. SignOps removes the token and posts device.removed |
| No token at all | The Push Notifications capability is missing, or the app runs in a Simulator that cannot get one |
Every reason Apple can answer is in APNs error codes.
Next
- Buttons on iOS come from a notification category your app registers. See Buttons and sounds.
- Order and ride tracking that updates in place: Live Activities (Starter and Pro).
- The same app on Android: Android push.