Logo for tanaschita.com

Registering for push notifications in SwiftUI

Learn how to request notification permissions and register for remote notifications in a SwiftUI app.

01 Jun 2026 · 7 min read

Push notifications allow us to inform users about updates even when they are not actively using the app.

Before an iOS app can receive remote notifications, we first need to register the app with Apple Push Notification service (APNs). This process includes requesting notification permission from the user, registering with APNs, and handling the generated device token.

In this article, we'll look at how to set up push notification registration in a SwiftUI app.

Let's dive in.

Sponsorship logo
Architecture & Design Patterns for iOS
This book is a practical guide to essential architectural principles and design patterns for iOS development. It covers strategies for building maintainable apps with Swift and SwiftUI, including dependency injection, navigation, common patterns, and modularization.
LEARN MORE

Overview

To register for push notifications, we need to:

  1. enable the push notifications capability
  2. request notification permission
  3. register with APNs
  4. handle the generated device token

Let's go through each step.

Enabling the push notifications capability

To enable push notifications, we first need to add the Push Notifications capability to the app target.

In Xcode, open the Signing & Capabilities tab and add the Push Notifications capability. This configures the required entitlement for the app and enables communication with APNs.

Requesting notification permission

Before the app can display notifications, the user needs to grant permission.

We can request authorization using UNUserNotificationCenter:

import UserNotifications
func requestNotificationPermission() async throws -> Bool {
try await UNUserNotificationCenter.current().requestAuthorization(
options: [.alert, .badge, .sound]
)
}

The authorization options define which notification features the app would like to use:

In practice, it is usually best to request permission in context, for example when the user enables a feature that benefits from notifications, instead of immediately on app launch.

Checking existing authorization status

Before prompting, it's worth checking whether the user has already made a decision. This avoids redundant permission requests and lets us call registerForRemoteNotifications() directly if permission has already been granted:

func configureNotifications() async throws {
let center = UNUserNotificationCenter.current()
let settings = await center.notificationSettings()
switch settings.authorizationStatus {
case .notDetermined:
let granted = try await center.requestAuthorization(options: [.alert, .badge, .sound])
if granted {
await registerForRemoteNotifications()
}
case .authorized, .provisional:
await registerForRemoteNotifications()
default:
break
}
}
@MainActor
func registerForRemoteNotifications() {
UIApplication.shared.registerForRemoteNotifications()
}

Registering with APNs

Once permission has been granted, we can register the app with APNs:

UIApplication.shared.registerForRemoteNotifications()

This starts the registration process with Apple Push Notification service.

If registration succeeds, iOS generates a device token and passes it back to the app.

Integrating an AppDelegate in SwiftUI

Even in SwiftUI apps, remote notification registration callbacks are still delivered through the app delegate.

To integrate an app delegate into a SwiftUI app, we can use UIApplicationDelegateAdaptor:

@main
struct ExampleApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self)
private var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

Receiving the device token

Once registration succeeds, the app delegate receives the generated device token:

final class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
print("Device token: \(tokenString)")
// Send tokenString to your server
}
}

The device token is provided as Data, so we need to convert it to a hex string before sending it to a backend. The snippet above maps each byte to a zero-padded two-digit hex representation and joins them into a single string, which is the format most push notification services expect.

The token itself uniquely identifies the app installation on the device. In most cases it is forwarded to a backend server, which then uses it to send push notifications through APNs.

Handling registration failures

If registration fails, iOS calls a different app delegate method:

func application(
_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error
) {
print("Failed to register: \(error)")
}

This can happen, for example, if push notifications are unavailable on the device or if the simulator is used.

Testing push notification registration

Notification permissions and notification handling can both be tested in the simulator.

Xcode allows us to simulate remote notifications by sending .apns payload files to the app. This is useful for testing notification UI, payload handling, and navigation flows during development.

However, the simulator is not fully registered with Apple Push Notification service in the same way as a physical device. For example, real APNs delivery and production device token workflows should still be tested on actual hardware.

A note on device tokens

Device tokens are not guaranteed to stay the same forever.

For example, they can change after:

  • reinstalling the app
  • restoring a device backup
  • switching devices

Because of this, apps should treat the device token as dynamic and keep the backend updated whenever a new token is received.

A note on provisional authorization

There is an additional authorization option worth knowing about: .provisional. It allows the app to deliver quiet notifications to Notification Center without showing the standard permission prompt upfront. The user can then decide whether to keep receiving notifications or turn them off.

While this can be useful for certain strategies, it is worth testing carefully. Provisional notifications are delivered quietly by default, and the exact upgrade path to prominent notifications can feel less predictable across iOS versions and user settings.

Sponsorship logo
Preparing for a technical iOS job interview
Preparing for a technical iOS Job Interview with over 300 questions & answers. Covering Swift & Objective-C, SwiftUI & UIKit, Combine, HTTP Networking, iOS File System, Core Data, Concurrency with async/await, Security, Automated Testing, Dependency Management, AI & Machine Learning and more.
LEARN MORE
Sponsorship logo
Architecture & Design Patterns for iOS
This book is a practical guide to essential architectural principles and design patterns for iOS development. It covers strategies for building maintainable apps with Swift and SwiftUI, including dependency injection, navigation, common patterns, and modularization.
LEARN MORE
Sponsorship logo
Become a sponsor of tanaschita.com
By publishing an article on different iOS topics every week, tanaschita.com is constantly growing in the developer community and may provide a great audience for you as a sponsor.
CLICK TO LEARN MORE

Newsletter

Image of a reading marmot
Subscribe

Like to support my work?

Say hi

Related tags

Articles with related topics

notifications

swift

ios

Adding text input actions to iOS push and local notifications

Learn how to let users reply directly inside a notification.

15 Dec 2025 · 4 min read

Latest articles and tips

© 2026 tanaschita.com

Privacy policy

Impressum