How To Test Remote Push Notifications With iOS Simulators

9 min read

This article helps you to quickly test and send iOS remote push notifications in a SwiftUI or UIKit app using the simulator. Discover the various push notification types, such as background, alerts, VoIP, and how to add custom notification sounds.

Amos G.
Amos G.
Published November 21, 2023
Remote notifications header

In iOS, developers can create and send user notifications locally or remotely from a server through the Apple Push Notification Service (APNs). Enabling remote push notifications in iOS apps requires setting up a server to communicate with the APNs for a production app. However, using the simulator, you can quickly emulate and debug remote push notifications without APNS and a company server. Keep reading to learn how to configure and debug push notifications using the iOS simulator and your favorite command line tool.

Go Further

This article is a general overview tutorial for creating and testing remote push notifications using an iOS simulator. Check out the following resources to dive deep into regular and VoIP push notifications on iOS.

The completed SwiftUI demo project is available in our tutorial projects repository on GitHub. Download and test the alert push notification using a simulator and your favorite command line tool.

User Notifications Overview

Due to the events and updates in your iOS app, you may deliver up-to-date information to the user's device when the app is in the background or foreground. These user-facing notifications can communicate timely information regardless of the app's state, whether active or inactive. The content of a notification can include an alert, sound, and a badge for a visible notification. The diagram above illustrates the types of user notifications you can schedule to trigger locally through your app or remotely via communication between a provider server and APNs.

Benefits of User Notifications

  • Send real-time notification updates to your app. For example, an audio room app may alert participants when a new user joins an ongoing audio room conversation.
  • Power efficiency: User-facing notifications are power efficient. Sometimes, an app cannot deliver notifications when the battery level runs low. For example, if a new iOS version is available to download and install, the system can only install it if the battery is at least 50%. That is purposely done to save the battery of the device.
  • Push notifications create dynamic experiences. Particularly, alert pushes support interactivity, such as tapping to view details or using a flick gesture to dismiss the notification before it disappears. Users can tap and hold notifications to display a longer view without opening the app.
  • Support for background and foreground: An app to receive push notifications does not necessarily need to be running or inactive.
  • Easily customizable: Developers can customize visible push notifications' look, feel, and interaction styles.

Alert and Silent Notifications Overview

As demonstrated in the diagram above, local or remote notification can be delivered as a background notification (silent notification) or an alert notification. Background notifications do not have a visible UI because they notify the app, not the users. However, notifications delivered via alerts are visible to users.

Silent notifications are used for background app refresh, such as downloading information to keep the app up-to-date. Additionally, these notifications rely upon the device's power and time to decide the delivery of notifications.

Alert Push Notifications

Alert Push Notifications

The app’s users can interact with these visible alerts in various ways. The purpose of these notifications is to inform users about new information they can interact with. In a video conferencing app like Zoom, push notifications are used to notify meeting participants when another call participant joins or leaves the meeting.

Similarly, in a live streaming app like Twitch or an audio room app like Club House, push notifications are used to inform guests when the room or stream goes live.

Visible alerts (notifications) do not require the app to run before they can be delivered. For example, when a user sends a chat app to the background and launches a video calling app, the chat app can still receive real-time data while in the background.

Background Push Notifications

These notifications are not displayed using sound or a badge. They are server-based and inform the app about necessary updates. Delivering background notifications does not require setting user permissions or sending an approval request.

Alert Notification Content

A typical alert notification consists of:

  • Content: The title and a short description of the type of notification you want to display to users.
  • Trigger: When and how to show the notification.
  • Request: Registers the notification content and triggers to the system.

The content of the notification is called a payload. The payload contains the information you want to deliver to users as a notification. You can construct the notification payload with a series of fields using a JSON dictionary.

Note: The maximum size of a regular remote notification payload cannot exceed 4KB. Similarly, the payload size for VoIP notifications cannot exceed 5KB.

Create the Remote Notification Payload

The code snippet below demonstrates the typical structure of a push notification payload and its parts. It is an example notification payload with an alert dictionary for a video-conferencing application that alerts participants whenever a team member joins a meeting call.

{
        "aps" : {
       "alert" : {
            "title" : "All Hands",
            "body" : "Amos has joined the meeting"
        },
        "sound" : "default",
        "badge" : 10,
   },
    "duration": "Current time",
    "startedAt": "Meeting’s starting time"
}

An alert notification payload consists of an aps dictionary. The aps dictionary contains Apple-defined keys and information about how to render the notification. The alert dictionary contains a title field and a short, human-readable notification description. The sound field is optional. You can specify this field to play audio when the app receives a notification. The sound field can use the specified default or a custom sound. Like the sound field, the badge is optional. It is an absolute value for overriding the app’s icon. The other fields can be used to specify custom data. In this example, the duration of the meeting and its starting time are custom data fields.

For our demo notification app to be able to recognize the payload and display the alert notification using a simulator, it is required to specify the app's Bundle Identifier in the payload. The bundle identifier should be placed above the aps dictionary "Simulator Target Bundle": "com.amosgyamfi.AlertPushNotifications".

Create a Payload With an Alert String

Instead of describing a visible notification alert with a dictionary, you can use a string, as shown in the snippet below.

{
  "Simulator Target Bundle": "com.amosgyamfi.AlertPushNotifications",
  "aps": {
    "alert": "Amos has joined the meeting!",
    "sound": "default",
    "badge": 1
  }
}

To create a JSON dictionary for our notification app's payload, follow the instructions below. Start with a new SwiftUI project in Xcode.

  1. Press Control on the keyboard and click anywhere in the Xcode Project bundle to add a new JSON file.
  2. Select GeoJSON File from the dialog window.
Create a json file
  1. Name the file, for example, AlertPushNotification, and follow the next instructions to create it.
  2. Xcode will add the extension .geojson to the file. Change the extension to .apns. The file name in step 3 above becomes AlertPushNotification.apns. The file is a certificate for the Apple Push Notification service (APNs)
  3. Finally, replace the file's content with the sample snippet below.
{
    "Simulator Target Bundle": "com.amosgyamfi.AlertPushNotifications",
    "aps" : {
       "alert" : {
            "title" : "All Hands",
            "body" : "Amos has joined the meeting"
        },
        "sound" : "default",
        "badge" : 10,
   },
    "duration": "Current time",
    "startedAt": "Meeting’s starting time"
}

Configure Your App For Alert Notifications

Building your own app? Get early access to our Livestream or Video Calling API and launch in days!
 Alert Notification

You can configure your app to send and display remote alert notifications for inactive and active app states. The delivered notification may appear on the device's lock screen, Dynamic Island, Notifications Center, or from the top edge of the device's screen. The first step is registering the device to receive pushes from APNs. In this case, setting up APNs requires communicating with your provider server to send notifications.

This article will focus mainly on testing remote notifications using the iOS simulator. A later article will cover using APNs to send and receive remote notifications. Let’s create a new SwiftUI app, AlertPushNotifications. Follow the steps below to configure the remote notifications.

  1. Declare UNUserNotificationCenterDelegate in AppDelegate. Doing so will assign your AppDelegate as a delegate of the notification center and will notify the app when a user opens the alert. SwiftUI does not implement an AppDelegate by default, so you should implement it in the app's conformer file.
swift
1
2
3
4
5
6
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate { func application (_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { registerForNotifications() return true } }
  1. Ask the user's permission to show alert notifications by calling the requestAuthorization method.
swift
1
2
3
4
5
6
7
8
// MARK: Request user permissions func registerForNotifications() { UNUserNotificationCenter.current() .requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in print("Permission granted: \(granted)") } }
  1. Set up registration callback functions to check whether the registration fails or succeeds and display the notification.
swift
1
2
3
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.banner, .sound]) }
  1. Connect the AppDelegate class to the SwiftUI app’s lifecycle @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate.

Let’s combine all the steps above in the main SwiftUI project file AlertPushNotificationsApp.app.

swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// // AlertPushNotificationsApp.swift // AlertPushNotifications import UIKit import SwiftUI import UserNotifications // Step 1. Declare `UNUserNotificationCenterDelegate` class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate { func application (_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { registerForNotifications() return true } // Step 2. Ask the user's permission to show alert notifications by calling the `requestAuthorization` method. func registerForNotifications() { UNUserNotificationCenter.current() .requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in print("Permission granted: \(granted)") } } // Step 3. Set up registration callback functions to check whether the registration fails or succeeds and display the notification. func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.banner, .sound]) } } // MARK: Connect the app delegate to the SwiftUI app lifecycle @main struct AlertPushNotificationsApp: App { // Step 4. Connect the `AppDelegate` class to the SwiftUI app’s lifecycle @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { WindowGroup { ContentView() } } }

Test the Alert Notification With an iOS Simulator

At this point, we have set up the remote notification with the AppDelegate class and created a payload to show the notification. It is now time for the exciting moment: testing.

Run the app and place the running simulator on the side of the Xcode's window.
Lock the device screen of the simulator by pressing cmd + l to show the home screen.
Drag your APNs certificate file AlertPushNotification.apns to the simulator.

Bravo! You can now see the notification displaying with a default sound.

Specify a Custom Notification Sound

The above alert notification example uses the iOS default sound when displaying the notification. To provide a custom notification sound experience:

  1. Add an audio file with an extension .mp3, .aiff, or .m4a to the Xcode’s project bundle. The example in this section uses a -5dB notification sound from Meta’s Sound Kit.
  2. Specify the custom sound AlertSound.m4a in the payload as shown below.
{
  "Simulator Target Bundle": "com.amosgyamfi.AlertPushNotifications",
  "aps": {
    "alert": "Amos has joined the meeting!",
    "sound": "AlertSound.m4a",
    "badge": 1
  }
}

Now, dragging the APNs certificate file AlertPushNotification.apns to the simulator will play the custom sound when displaying the alert.

How to Send Notifications Through the Command Line

You can send push notifications using your favorite command line tool, such as Terminal or Warp. Follow the steps below to configure and receive alert pushes through the terminal.

  1. Get the iOS simulator’s identifier from Xcode. Go to the Toolbar and click Window -> Devices and Simulators.
Device simulators
  1. Find the identifier of the selected iOS simulator under the Simulators tab. Select and the identifier 92BE6788-0D03-4801-AAA0-C3A42EB92790.
Simulator identifier
  1. Obtain the bundle identifier of the project com.amosgyamfi.AlertPushNotifications. Select the main app’s folder and click General to find the project’s bundle ID.
Bundle identifier
  1. Specify the path of the alert notification payload file /Users/amos.gyamfigetstream.io/Desktop/StreamDevRel/2024/AlertPushNotifications/AlertPushNotifications. Navigate to the Xcode project’s source folders, find the payload file, and copy its path.
Playload path
  1. Run the following command in Terminal or Warp xcrun simctl push 92BE6788-0D03-4801-AAA0-C3A42EB92790 com.amosgyamfi.AlertPushNotifications Desktop/StreamDevRel/2024/AlertPushNotifications/AlertPushNotifications/AlertPushNotification.apns.
Terminal command

The command above is used to send the payload via the command line and communicate with the selected iOS simulator.

After sending the command, the alert push notification will display from the top edge of the simulator with a sound and disappear after a few seconds.

What's Next?

This article introduced you to using the iOS simulator in testing and sending remote push notifications. It covered the creation of a notification payload and testing it through the command line to display alert notifications. Check out the related links to learn more about push notifications for chat messaging and iOS Voice Over IP (VoIP) apps.

Integrating Video With Your App?
We've built a Video and Audio solution just for you. Check out our APIs and SDKs.
Learn more ->