What you're actually testing when you test notifications
Testing notifications in Xcode means checking whether your app sends the right message to the right person at the right time, and whether the person can actually see it and act on it. You're not testing Apple's notification system — you're testing your own code that decides when to send a notification, what it says, and what happens when someone taps it.
The simulator built into Xcode can show you what a notification looks like on screen. The real device testing tells you whether notifications actually arrive when your app is closed or in the background. Most developers need both, because the simulator and a real phone behave differently in ways that matter.
This guide covers the tools Xcode gives you, how to use them without getting lost in Apple's documentation, and what to actually check before you ship a notification feature to real people.
Key Takeaways
- The Xcode simulator can display local notifications (ones your app sends itself) but cannot receive remote notifications (ones sent from a server), so you need a real device to test push notifications.
- Local notifications are easier to test in the simulator because you control the timing and content directly from your code.
- Remote notifications require a provisioning profile, a certificate, and a server that can actually send them — the simulator cannot fake this part.
- The most common mistake is testing only in the simulator and assuming remote notifications work, then discovering they don't on a real device.
- Xcode's console output and the system logs on a real device show you why a notification failed to arrive, if you know where to look.
Testing local notifications in the Xcode simulator
A local notification is one your app schedules itself — a reminder, an alarm, a "time to take a break" message. The simulator can show you exactly what it looks like when it arrives on screen. Open Xcode, build your app to the simulator, and trigger the code that sends the notification. The notification appears in the simulator's notification center just as it would on a real phone.
To see the notification on the lock screen or as a banner, you need to send the app to the background first. Tap the home button (or swipe up from the bottom on newer simulators), then wait for the notification to fire. It will appear exactly as a user would see it. Tap it, and your app should open and respond to that tap — that's the part you need to verify actually works.
Check three things: Does the notification appear with the right text? Does tapping it open your app? Does your app do the right thing when it opens (navigate to the right screen, show the right content). If any of those fail in the simulator, your local notification code has a bug.
Testing remote notifications requires a real device
A remote notification (also called a push notification) comes from a server, not from your app itself. The simulator cannot receive these because it has no connection to Apple's push notification service. You must test on a real iPhone or iPad.
Before you can test remote notifications, you need three things: a provisioning profile that includes push notification permissions, a certificate signed by Apple that your server can use to send notifications, and a server (or a testing tool) that actually sends the notification. If any of these is missing or misconfigured, the notification will not arrive, and you will not know why from the simulator alone.
The provisioning profile comes from Apple Developer. The certificate is generated in Xcode or in the Apple Developer portal. Both are tied to your app's bundle identifier and your Apple Developer account. If you change the bundle identifier, the old certificate and profile stop working.
How to send a test remote notification from your Mac
Apple provides a command-line tool called simctl that can simulate a remote notification on a real device connected to your Mac via USB. This is the fastest way to test without building a server.
First, find your device's unique identifier. Plug the device into your Mac, open Xcode, and go to Window > Devices and Simulators. Find your device in the list and look for the identifier — it's a long string of letters and numbers. Copy it.
Next, create a JSON file with the notification payload. Save it as notification.json (or any name you choose) with content like this:
{ "aps": { "alert": { "title": "Test Notification", "body": "This is a test message" }, "sound": "default", "badge": 1 } }
Then run this command in Terminal, replacing DEVICE_ID with your actual device identifier and BUNDLE_ID with your app's bundle identifier:
xcrun simctl push DEVICE_ID BUNDLE_ID notification.json
The notification arrives on your device when ready. If it does not appear, check the device's console output in Xcode (Window > Devices and Simulators, select your device, click the console icon at the bottom) for error messages.
Reading the console to find out why a notification failed
When a notification does not arrive, the console output on your device or in Xcode often tells you why. Connect your device to your Mac, open Xcode, go to Window > Devices and Simulators, select your device, and look at the console at the bottom of the window. Run your notification code or send a test notification and watch for error messages.
Common messages you might see: "No valid 'aps-environment' entitlement string found for process" means your provisioning profile does not have push notification permission. "Certificate is invalid" means your signing certificate has expired or is not installed on your Mac. "Device token not available" means your app has not yet registered with Apple's push service — this happens automatically when your app first launches, but it takes a few seconds.
If you see nothing in the console and the notification still does not arrive, the problem is usually on the server side — the certificate your server is using to send the notification is wrong, or the device token you sent to the server is outdated or incorrect.
Testing what happens when someone taps the notification
A notification is only useful if tapping it does something. You need to test both what happens when your app is running and what happens when it is closed.
When your app is running, the notification arrives in the foreground. By default, iOS does not show a banner or sound — it just delivers the notification to your code. You have to handle it in your app's notification delegate method (usually userNotificationCenter(_:willPresent:withCompletionHandler:) in Swift). Test that your code actually runs and does what you expect.
When your app is closed, the user sees the notification on the lock screen or in the notification center. Tapping it launches your app and delivers the notification to a different delegate method (userNotificationCenter(_:didReceive:withCompletionHandler:)). Your code should navigate to the right screen or show the right content based on which notification was tapped. Test this by closing your app completely, sending a notification, waiting for it to arrive, and tapping it. Watch whether your app opens to the correct place.
Common mistakes that waste testing time
The biggest mistake is testing only in the simulator and assuming remote notifications work. They do not work in the simulator at all — you will discover this only when you test on a real device. Always test remote notifications on a real device before you ship.
The second mistake is not checking whether your app actually has permission to receive notifications. On a real device, go to Settings > Notifications > [Your App Name] and verify that notifications are turned on. If they are off, no notification will arrive, no matter what your code does. This is a user setting, not a code bug, but you need to know the difference.
The third mistake is using an outdated device token. A device token is a unique identifier that your server uses to send a notification to a specific device. Tokens can change when the user updates iOS, reinstalls your app, or changes certain settings. If your server is using an old token, the notification will not arrive. Always get a fresh token from the device and send it to your server every time your app launches.
The fourth mistake is not testing with the app closed. Many developers test only with the app running in the foreground, where notifications behave differently. Always test with the app in the background and completely closed, because that is how real users will experience notifications most of the time.
Frequently Asked Questions
Can I test remote notifications without a real device?
No. The Xcode simulator cannot connect to Apple's push notification service, so it cannot receive remote notifications. You must use a real iPhone or iPad. You can use the simctl command-line tool to send test notifications to a real device without building a server, which is faster than setting up a full backend.
Why does my notification appear in the simulator but not on my real device?
If it is a local notification, check that your device has notifications enabled for your app in Settings. If it is a remote notification, the problem is usually an expired certificate, an invalid provisioning profile, or an outdated device token. Check the device console in Xcode for specific error messages.
How do I know if my device token is valid?
Your app receives the device token automatically when it registers for notifications. Log it to the console when your app launches, and verify that it is a long hexadecimal string (not empty or nil). If it is empty, your app has not registered yet — wait a few seconds and try again. If it stays empty, check that notifications are enabled for your app in Settings.
What is the difference between a provisioning profile and a certificate?
A provisioning profile is a file that tells iOS that your app is allowed to use certain features, including push notifications. A certificate is a file that your server uses to prove to Apple that it is allowed to send notifications on behalf of your app. You need both. The profile goes on your device; the certificate goes on your server.
Do I need to test notifications on every iOS version?
Test on the oldest iOS version your app supports and the newest version available. Notification behavior has changed between versions, and a notification that works on iOS 16 might not work the same way on iOS 15. If you support multiple versions, test on at least two devices running different versions.