How to test notifications in Xcode before sending them to users
Testing notifications in Xcode means running your app in the simulator or on a physical device and triggering notification code to see whether the alert appears, the sound plays, and the badge updates correctly. You do this by writing test code that calls your notification methods, using the simulator's built-in notification features, or sending test payloads through Xcode's debugging tools. The fastest way is to add a button to your app that fires a local notification when tapped, then watch what happens on screen.
Most developers test notifications in two stages: first in the simulator while building, then on a real device before release. The simulator can show you visual alerts and badge counts, but it cannot play the actual device sounds or test certain behaviors like background delivery. A physical device shows you the real user experience, including how notifications look on the lock screen and in the notification center.
Key Takeaways
- The fastest way to test is to add a button in your app that triggers a local notification when tapped, so you can see the result immediately.
- The Xcode simulator can show visual alerts and badge counts, but does not play device sounds or test background notification delivery accurately.
- Testing on a physical device connected to Xcode shows you the real lock screen appearance, sounds, and how notifications behave when your app is closed.
- Use the UserNotificationCenter API to schedule local notifications during development, and check the system notification settings to confirm your app has permission.
- Remote notifications (push notifications) require a provisioning profile and Apple Push Notification service certificate, so most developers test those after local notification testing works.
Setting up a test button to trigger local notifications
The simplest way to test is to add a button in your view controller or SwiftUI view that calls your notification code. In SwiftUI, create a button that fires a function containing your notification logic. In UIKit, add a UIButton with a target action that does the same thing.
Inside that function, use UNUserNotificationCenter to request permission and schedule a notification. First, request authorization from the user by calling requestAuthorization(options:completionHandler:). Then create a UNMutableNotificationContent object, set the title, body, and sound, and wrap it in a UNTimeIntervalNotificationTrigger to fire after a few seconds. Finally, create a UNNotificationRequest and add it to the notification center using add(_:withCompletionHandler:).
When you tap the button in the simulator, the notification should appear after the delay you set. If it does not appear, check the console for errors and verify that the notification center received the request without throwing an exception.
Testing notifications in the Xcode simulator
The simulator can display local notifications and show badge counts on your app icon. To see a notification appear, run your app in the simulator, tap your test button, and wait for the trigger time to pass. The notification will appear as a banner at the top of the screen or in the notification center, depending on your app's focus state and your notification content settings.
If your app is in the foreground when the notification fires, it will not display a banner by default — instead, your app's UNUserNotificationCenterDelegate method userNotificationCenter(_:willPresent:withCompletionHandler:) will be called. You must tell the delegate to show the notification by passing .banner or .list to the completion handler. Without this, the notification fires silently in the background.
The simulator does not play notification sounds, vibrations, or haptic feedback. It also does not accurately simulate background notification delivery or the behavior of notifications when your app is suspended. For those scenarios, you must test on a physical device.
Testing on a physical device connected to Xcode
Connect your iPhone or iPad to your Mac with a USB cable, select it as the build target in Xcode, and run your app. When you tap your test button, the notification will behave exactly as it would for a real user — it will play the sound, show on the lock screen, and appear in the notification center.
Testing on a device also lets you verify that your app has the correct notification permissions. Go to Settings on the device, find your app, and check that notifications are enabled. If your app requests permission and the user denies it, your notification code will still run, but the notification will not display. Your test button should still work without crashing, even if permission was denied.
If you want to test how your app behaves when a user taps a notification, you can trigger the notification and then tap it while the app is running or suspended. This calls your userNotificationCenter(_:didReceive:withCompletionHandler:) delegate method, where you can log the action or navigate to a specific screen.
Checking notification permissions and settings
Before testing, confirm that your app has requested notification permission and that the user has granted it. Call UNUserNotificationCenter.current().getNotificationSettings(completionHandler:) to check the current authorization status. The completion handler receives a UNNotificationSettings object with an authorizationStatus property that tells you whether the user has granted, denied, or not yet responded to the permission request.
If the status is .notDetermined, the permission prompt has not been shown yet. If it is .denied, the user has refused notifications and you will need to ask them to enable it in Settings. If it is .authorized, your notifications should display normally.
You can also check individual notification settings like soundSetting, badgeSetting, and alertSetting to see which features the user has enabled. This helps you understand why a notification might not be displaying as expected.
Debugging notification delivery with the console
When you schedule a notification, Xcode's console will print messages if something goes wrong. Add print statements in your notification code to track whether the request was created, whether permission was granted, and whether the notification center accepted the request without error.
If a notification does not appear, check the console for error messages. Common issues include scheduling a notification with a trigger time in the past (it fires immediately instead of waiting), forgetting to request permission before scheduling, or setting the notification content to empty (no title or body means nothing displays).
You can also use Xcode's breakpoints to pause execution when your notification code runs. Set a breakpoint on the line where you call add(_:withCompletionHandler:) and inspect the UNNotificationRequest object to verify that the content and trigger are set correctly.
Testing remote notifications and push certificates
Remote notifications (push notifications sent from your server) require more setup than local notifications. You need a provisioning profile that includes the push notification capability, and you need an Apple Push Notification service certificate from your Apple Developer account. Most developers test local notifications first, then move to remote notifications once the local flow is working.
To test remote notifications in the simulator, you can use a tool like Pusher or Apple's Notification Composer (available in Xcode 11.4 and later) to send test payloads. These tools let you craft a JSON payload and send it to your app without needing a full backend server. On a physical device, you can use the same tools or ask your backend team to send a test push from your production or staging server.
Remote notification testing is more complex because it involves your server, Apple's push service, and network timing. Start with local notifications to confirm your notification handling code works, then add remote notifications once you have that foundation in place.
Frequently Asked Questions
Why does my notification not appear when my app is in the foreground?
By default, notifications do not display a banner when your app is active. You must implement the userNotificationCenter(_:willPresent:withCompletionHandler:) delegate method and pass .banner or .list to the completion handler to show it. Without this, the notification fires silently and your delegate method receives it, but the user sees nothing on screen.
Can I test notifications in the simulator without a physical device?
Yes, the simulator can display local notifications and badge counts. However, it does not play sounds, vibrations, or haptic feedback, and it does not accurately simulate background notification delivery. For a complete test, you should eventually test on a physical device, but the simulator is fine for early development and debugging your notification code.
What should I do if my notification permission request never appears?
Permission requests only appear once per app install. If you denied it during testing, you must uninstall the app from the simulator or device and reinstall it. Alternatively, go to Settings, find your app, and toggle notifications off and back on to reset the permission state.
How do I test what happens when a user taps a notification?
Implement the userNotificationCenter(_:didReceive:withCompletionHandler:) delegate method, which is called when the user taps a notification. Inside this method, you can log the action, navigate to a specific screen, or update your app state. Trigger a test notification and tap it to verify this method is called with the correct data.
Do I need a real Apple Developer account to test notifications?
For local notifications, no — you can test those in the simulator or on a device without any developer account. For remote notifications (push), you need an Apple Developer account to create a provisioning profile and push certificate. Most developers test local notifications first, then set up the developer account when they are ready to test push notifications.