iPhone
push notifications
user settings
app development
iOS features

Determine on iPhone if user has enabled push notifications

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

To check whether a user has enabled push notifications on iOS, you use UNUserNotificationCenter.current().getNotificationSettings(). This async method returns a UNNotificationSettings object with an authorizationStatus property that tells you whether notifications are authorized, denied, provisional, or not yet requested. The approach differs between modern iOS (10+) and legacy versions, and you should always check status before attempting to send or schedule notifications.

Modern Approach: UNUserNotificationCenter (iOS 10+)

swift
1import UserNotifications
2
3func checkNotificationStatus() {
4    UNUserNotificationCenter.current().getNotificationSettings { settings in
5        switch settings.authorizationStatus {
6        case .authorized:
7            print("Notifications are enabled")
8        case .denied:
9            print("Notifications are denied — user must enable in Settings")
10        case .notDetermined:
11            print("User hasn't been asked yet")
12        case .provisional:
13            print("Provisional notifications enabled (quiet delivery)")
14        case .ephemeral:
15            print("Ephemeral notifications (App Clips)")
16        @unknown default:
17            print("Unknown status")
18        }
19    }
20}

The callback runs on a background thread — dispatch to the main queue for UI updates:

swift
1UNUserNotificationCenter.current().getNotificationSettings { settings in
2    DispatchQueue.main.async {
3        if settings.authorizationStatus == .authorized {
4            self.showNotificationBadge()
5        } else {
6            self.showEnableNotificationsPrompt()
7        }
8    }
9}

Checking Individual Notification Types

Beyond the overall authorization, you can check specific delivery methods:

swift
1UNUserNotificationCenter.current().getNotificationSettings { settings in
2    print("Alerts: \(settings.alertSetting == .enabled)")
3    print("Badges: \(settings.badgeSetting == .enabled)")
4    print("Sounds: \(settings.soundSetting == .enabled)")
5    print("Lock screen: \(settings.lockScreenSetting == .enabled)")
6    print("Notification center: \(settings.notificationCenterSetting == .enabled)")
7    print("Critical alerts: \(settings.criticalAlertSetting == .enabled)")
8
9    // Each setting can be .enabled, .disabled, or .notSupported
10}

A user might have notifications authorized but alerts disabled — they would only receive badge updates.

Requesting Permission

If the status is .notDetermined, request permission:

swift
1func requestNotificationPermission() {
2    UNUserNotificationCenter.current().getNotificationSettings { settings in
3        guard settings.authorizationStatus == .notDetermined else { return }
4
5        UNUserNotificationCenter.current().requestAuthorization(
6            options: [.alert, .badge, .sound]
7        ) { granted, error in
8            if granted {
9                DispatchQueue.main.async {
10                    UIApplication.shared.registerForRemoteNotifications()
11                }
12            }
13            if let error = error {
14                print("Error requesting notifications: \(error)")
15            }
16        }
17    }
18}

Using async/await (iOS 15+)

swift
1func checkAndRequestNotifications() async -> Bool {
2    let center = UNUserNotificationCenter.current()
3    let settings = await center.notificationSettings()
4
5    switch settings.authorizationStatus {
6    case .authorized, .provisional:
7        return true
8    case .notDetermined:
9        do {
10            let granted = try await center.requestAuthorization(options: [.alert, .badge, .sound])
11            if granted {
12                await MainActor.run {
13                    UIApplication.shared.registerForRemoteNotifications()
14                }
15            }
16            return granted
17        } catch {
18            return false
19        }
20    case .denied, .ephemeral:
21        return false
22    @unknown default:
23        return false
24    }
25}

Directing Users to Settings

Once a user denies notifications, you cannot re-prompt them. The only option is to direct them to the Settings app:

swift
1func openNotificationSettings() {
2    if let url = URL(string: UIApplication.openSettingsURLString) {
3        UIApplication.shared.open(url)
4    }
5}
6
7// Show a custom UI explaining why they should enable notifications
8func promptToEnableInSettings() {
9    let alert = UIAlertController(
10        title: "Enable Notifications",
11        message: "Turn on notifications in Settings to receive updates.",
12        preferredStyle: .alert
13    )
14    alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { _ in
15        self.openNotificationSettings()
16    })
17    alert.addAction(UIAlertAction(title: "Not Now", style: .cancel))
18    present(alert, animated: true)
19}

SwiftUI Integration

swift
1import SwiftUI
2import UserNotifications
3
4class NotificationManager: ObservableObject {
5    @Published var isAuthorized = false
6    @Published var isDenied = false
7
8    func checkStatus() {
9        UNUserNotificationCenter.current().getNotificationSettings { settings in
10            DispatchQueue.main.async {
11                self.isAuthorized = settings.authorizationStatus == .authorized
12                self.isDenied = settings.authorizationStatus == .denied
13            }
14        }
15    }
16}
17
18struct ContentView: View {
19    @StateObject private var notifications = NotificationManager()
20
21    var body: some View {
22        VStack {
23            if notifications.isAuthorized {
24                Text("Notifications are enabled")
25            } else if notifications.isDenied {
26                Button("Enable in Settings") {
27                    if let url = URL(string: UIApplication.openSettingsURLString) {
28                        UIApplication.shared.open(url)
29                    }
30                }
31            }
32        }
33        .onAppear { notifications.checkStatus() }
34    }
35}

Legacy Approach (pre-iOS 10)

swift
1// Deprecated — only use for iOS 9 and earlier support
2if UIApplication.shared.isRegisteredForRemoteNotifications {
3    let types = UIApplication.shared.currentUserNotificationSettings?.types ?? []
4    if types.contains(.alert) || types.contains(.badge) || types.contains(.sound) {
5        print("Notifications enabled")
6    }
7}

Common Pitfalls

  • Checking status synchronously: getNotificationSettings is async. Calling it and immediately checking a flag before the callback runs gives stale results. Always use the completion handler or await.
  • Confusing .authorized with registered for remote: authorizationStatus == .authorized means the user approved local and remote notification display. You still need to call registerForRemoteNotifications() separately to get a device token for push.
  • Re-requesting after denial: requestAuthorization does nothing if the user already denied — it returns false immediately without showing a prompt. You must direct users to Settings.
  • Not rechecking on app foreground: Users can change notification settings at any time. Check status in applicationDidBecomeActive or sceneDidBecomeActive to stay current.
  • Provisional notifications: .provisional means quiet delivery (notification center only, no alerts or sounds). Do not treat it the same as .authorized for features that rely on visible alerts.

Summary

  • Use UNUserNotificationCenter.current().getNotificationSettings() to check notification status (iOS 10+)
  • Check authorizationStatus for overall permission and individual settings (alerts, badges, sounds) for specific capabilities
  • Request permission only when status is .notDetermined — denied users must go to Settings
  • Use UIApplication.openSettingsURLString to deep-link users to your app's Settings page
  • Recheck notification status on every app foreground since users can change settings at any time
  • Use async/await on iOS 15+ for cleaner notification permission flows

Course illustration
Course illustration

All Rights Reserved.