Push Notifications
Push Notifications
Enable push capability, request user permission, and register with APNs to receive device tokens.
Request Permission
Request permission to send push notifications to the user.
Syntax:
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound])
Example
import SwiftUI
import UserNotifications
struct PushPermissionDemo: View {
@State private var status: UNAuthorizationStatus? = nil
var body: some View {
VStack(spacing: 12) {
Text("Status: \(statusLabel)")
Button("Request Permission") {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound]) { _, _ in
UNUserNotificationCenter.current().getNotificationSettings { s in
DispatchQueue.main.async { status = s.authorizationStatus }
}
}
}
}
.padding()
.onAppear {
UNUserNotificationCenter.current().getNotificationSettings { s in
DispatchQueue.main.async { status = s.authorizationStatus }
}
}
}
private var statusLabel: String {
switch status { case .authorized?: return "authorized"
case .denied?: return "denied"
case .notDetermined?: return "notDetermined"
case .provisional?: return "provisional"
case .ephemeral?: return "ephemeral"
default: return "unknown" }
}
}
import SwiftUI
struct ContentView: View { var body: some View { PushPermissionDemo() } }
import SwiftUI
@main
struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } }
The example above shows a simple push permission request with a button to request access and a label to display the current status.
Foreground Presentation
Present notifications when the app is in the foreground.
Syntax:
UNUserNotificationCenter.current().getNotificationSettings { s in ... }
Example
import SwiftUI
struct ForegroundPresentationDemo: View {
@State private var last = "(none)"
var body: some View {
VStack(spacing: 12) {
Text("Last received: \(last)")
Button("Simulate Delivery") { last = Date().formatted() }
Text("Tip: Use UNUserNotificationCenterDelegate in your app to choose banner/sound when active.")
.font(.footnote)
.foregroundStyle(.secondary)
}
.padding()
}
}
import SwiftUI
struct ContentView: View { var body: some View { ForegroundPresentationDemo() } }
import SwiftUI
@main
struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } }
The example above shows a simple foreground presentation with a button to simulate delivery and a label to display the last received notification.
Request Authorization
Ask the user for permission and register for remote notifications.
Syntax:
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound])
Example
import SwiftUI
import UserNotifications
import UIKit
@main
struct MyApp: App {
init() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound]) { granted, _ in
if granted {
DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() }
}
}
}
var body: some Scene { WindowGroup { ContentView() } }
}
import UIKit
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("Device token: \(deviceToken)")
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("APNs registration failed: \(error)")
}
}
This example requests notification permission, registers with APNs, and handles success/failure callbacks for the device token.
SwiftUI App + AppDelegate bridge
In SwiftUI, bridge your AppDelegate so token callbacks are delivered:
Example
import SwiftUI
import UserNotifications
import UIKit
@main
struct MyApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
init() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound]) { granted, _ in
if granted {
DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() }
}
}
UNUserNotificationCenter.current().delegate = appDelegate
}
var body: some Scene { WindowGroup { ContentView() } }
}
Handle Delivery (Foreground/Background)
Use UNUserNotificationCenterDelegate to control presentation in foreground and handle taps:
Example
import UserNotifications
import UIKit
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
// Foreground delivery: choose how to present when app is active
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.banner, .sound, .badge])
}
// User taps a notification
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
// Navigate to a screen based on response.notification.request.content.userInfo
completionHandler()
}
}
The example above shows a simple foreground presentation with a button to simulate delivery and a label to display the last received notification.
Categories & Actions
Define actions (buttons) and attach categories to notifications:
Example
import UserNotifications
let reply = UNTextInputNotificationAction(identifier: "REPLY",
title: "Reply",
options: [])
let mark = UNNotificationAction(identifier: "MARK",
title: "Mark Read",
options: [.authenticationRequired])
let category = UNNotificationCategory(identifier: "MESSAGE",
actions: [reply, mark],
intentIdentifiers: [],
options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
// Include "category": "MESSAGE" in your APNs payload to use these actions.
The example above shows a simple foreground presentation with a button to simulate delivery and a label to display the last received notification.
Testing & Troubleshooting
- Simulator: Cannot receive remote pushes; use a real device. You can test local notifications on Simulator.
- Environments: Device tokens differ between sandbox and production; send to the matching APNs environment.
- Keys/Certificates: Ensure APNs Auth Key (or certs) is valid and linked to your team; use the key ID and Team ID on your server.
- Capabilities: Push Notifications capability enabled; for content updates, also enable Background Modes → Remote notifications.
- Payload size: Keep payloads under APNs limits; include
content-available: 1for silent pushes. - Logging: Watch device logs in Xcode when registering to confirm token/registration errors.
Tip: Use your server to send notifications via the APNs HTTP/2 API using your key and your app's device tokens.