charelf
charelf

Reputation: 3825

SwiftUI ask notification permission on start without button

I would like to request the notification permission from the user on start, without having the user to press a particular button. How can I do this in Xcode 12.5?

Here is my App struct:

import SwiftUI
import UserNotifications

@main
struct KiwiApp: App {
    let persistenceController = PersistenceController.shared
    let center = UNUserNotificationCenter.current()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
        }
    }
}

Now in which place should I add this code to ask for permission?

center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
    
    if let error = error {
        // Handle the error here.
    }
    // Enable or disable features based on the authorization.
}

(from https://developer.apple.com/documentation/usernotifications/asking_permission_to_use_notifications)

I know I can add it as a function call to a button, but I would like to request the access without the user having to press anything, so basically when initialising the view. Or do I need to this somewhere in ContenView.swift?

Edit:

Short answer: put the request code in an init() function of the App Struct.

struct KiwiApp: App {
    let persistenceController = PersistenceController.shared
    let center = UNUserNotificationCenter.current()
    
    init() {
        center.requestAuthorization(options: [.sound , .alert , .badge ], completionHandler: { (granted, error) in
            if let error = error {
                // Handle the error here.
            }
            // Enable or disable features based on the authorization.
        })
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
        }
    }
}```

Upvotes: 3

Views: 5490

Answers (1)

Raja Kishan
Raja Kishan

Reputation: 18924

Use UIApplicationDelegateAdaptor

@main
struct KiwiApp: App {
    let persistenceController = PersistenceController.shared
    let center = UNUserNotificationCenter.current()
    
    
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
        }
    }
}

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        
        registerForNotification()
        return true
    }
    
    
    func registerForNotification() {
        //For device token and push notifications.
        UIApplication.shared.registerForRemoteNotifications()
        
        let center : UNUserNotificationCenter = UNUserNotificationCenter.current()
        //        center.delegate = self
        
        center.requestAuthorization(options: [.sound , .alert , .badge ], completionHandler: { (granted, error) in
            if ((error != nil)) { UIApplication.shared.registerForRemoteNotifications() }
            else {
                
            }
        })
    }
}

Or use init

@main
struct KiwiApp: App {
    let persistenceController = PersistenceController.shared
    let center = UNUserNotificationCenter.current()
    
    init() {
        registerForNotification()
    }
    
    func registerForNotification() {
        //For device token and push notifications.
        UIApplication.shared.registerForRemoteNotifications()
        
        let center : UNUserNotificationCenter = UNUserNotificationCenter.current()
        //        center.delegate = self
        
        center.requestAuthorization(options: [.sound , .alert , .badge ], completionHandler: { (granted, error) in
            if ((error != nil)) { UIApplication.shared.registerForRemoteNotifications() }
            else {
                
            }
        })
    }
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
        }
    }
}

Upvotes: 3

Related Questions