So, you’re building an iOS app and you’ve reached the part where you need to test push notifications. Congrats! 🎉 That means you’re almost done. But testing push notifications in Xcode, especially during development, can feel a little confusing—at least at first. Don’t worry, we’ll break it down step by step, and make it simple and even fun.
TL;DR: You can test push notifications in development using Xcode and a tool like the command line or Postman. Set up an APNs key or certificate, get your device token, and send a test push. Use breakpoints or logs to catch notification behavior in your app. We’ve got all the steps explained below.
📦 What You Need Before You Start
Before we dive into testing, make sure you have the following ready:
- A real iOS device (simulators can’t receive push notifications ❌)
- Your Apple Developer account
- An app with push notifications enabled
- Xcode (of course!)
Optional but helpful:
- Postman or a similar HTTP request tool
- A macOS terminal and some comfort using it
🔧 Step 1: Enable Push Notifications in Your App
First things first—make sure push notifications are enabled in your Xcode project.
- Open your project in Xcode
- Select your app target
- Go to the Signing & Capabilities tab
- Click the “+ Capability” button
- Add Push Notifications and Background Modes
- Under Background Modes, check Remote notifications
Done? Nice. Let’s move on!
🔑 Step 2: Get Your APNs Authentication Key or Certificate
To send any push notifications with Apple Push Notification service (APNs), you need permission from Apple. That means setting up an APNs key or certificate.
Option 1: Use an APNs Key (Easier)
This key never expires and is tied to your Apple Developer account.
- Go to the Apple Developer Portal
- Select Certificates, IDs & Profiles
- Go to Keys
- Click the “+” button to create a new key
- Name it and check Apple Push Notifications Service (APNs)
- Download the .p8 key and save your key ID and Team ID
Option 2: Use an APNs Certificate (Legacy)
This works too, but requires renewal and setup every year. Stick to the APNs key if possible.
📱 Step 3: Register for Push Notifications in Xcode
Add a bit of Swift code to ask users to allow notifications—and register your app with APNs.
import UserNotifications
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
print("Permission granted: \(granted)")
guard granted else { return }
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
In your AppDelegate, grab the device token:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")
}
Copy this token—you’ll need it for testing!

🚀 Step 4: Send a Test Push Notification
There are two main ways to send notifications for testing.
🧪 Option 1: Use Terminal and cURL
Use cURL and your .p8 key to send a push.”
curl -v \
--header "apns-topic: your.bundle.id" \
--header "apns-push-type: alert" \
--header "authorization: bearer <your_token>" \
--header "content-type: application/json" \
--data '{ "aps": { "alert": "Hello from Xcode!", "sound": "default" } }' \
--http2 https://api.development.push.apple.com/3/device/<your_device_token>
You’ll need to generate a JWT token for APNs. Tools like Knuff or JWT.io can help. Or go with Postman.
🧪 Option 2: Use Postman
Set up your headers and POST a push payload to
https://api.development.push.apple.com/3/device/<device_token>
Add:
authorization: bearer <JWT-token>apns-topic: your.bundle.idapns-push-type: alert
Remember: push tokens change. If your notification isn’t arriving, double-check your device token and JWT. Try again after restarting your build.
🐞 Step 5: Debug Notifications
Notifications not showing up? Try these tips:
- Set breakpoints in
didReceiveRemoteNotification - Add logging to console using
print() - Ensure your payload is correct (APNs is picky!)
- Check if your app is in foreground or background—behavior is different
If your app is in the foreground, it won’t show banners unless you handle it manually using:
UNUserNotificationCenter.current().delegate = self
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.banner, .sound])
}
🎯 Bonus: Test Silent Pushes
Want to send silent pushes? These are “content-available” notifications with no alert. They’re great for background updates.
{
"aps": {
"content-available": 1
},
"customKey": "customValue"
}
In your AppDelegate:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// Handle your background update
completionHandler(.newData)
}
👋 Final Thoughts
Testing push notifications may seem tricky, but once you get the hang of it, it’s super satisfying. Whether you’re shooting alerts to your test devices or debugging a silent push, it’s all part of the iOS adventure 🧭.
So go ahead—light up that screen with your first push. You earned it!
P.S. Don’t forget to clean up and revoke old keys or tokens after launch 😄
