Brandon Brunson
Brandon Brunson

Reputation: 1

SwiftUI doesn't update when variable is changed in appDelegate

I am trying to have the app check for whether notification access is available, then display ContentView if it is, or NotificationView if it isn't. What I have does this great, when it runs it checks and shows the right view. But, the NotificationView asks the user to allow permissions with a button. I want it so once the permission is granted, then it switches to the other view, but I can't seem to figure out how. I have also tried to do it with a sheet, but same problem.

Here is what I have:

appApp.swift

@main
struct appApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    @State private var notificationStatus: String = "na"
    
    var body: some Scene {
        WindowGroup {
            if appDelegate.notificationStatus == true {
                NotificationView()
            } else {
                ContentView()
            }
        }
    }
}

appDelegate.swift

class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    @Published var notificationStatus: Bool = false
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let center = UNUserNotificationCenter.current()
        center.getNotificationSettings { settings in
            switch settings.authorizationStatus {
            case .notDetermined:
                self.notificationStatus = false
            case .denied:
                self.notificationStatus = false
            case .authorized:
                self.notificationStatus = true
            case .provisional:
                self.notificationStatus = true
            case .ephemeral:
                self.notificationStatus = false
            @unknown default:
                self.notificationStatus = false
            }
        }
        return true
    }

Any help would be greatly appreciated, thanks everyone!

Upvotes: 0

Views: 92

Answers (1)

malhal
malhal

Reputation: 30746

Conform your delegate to ObservableObject, e.g.

class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate, ObservableObject {

Then keep the @UIApplicationDelegateAdaptor in the App but in your View use:

@EnvironmentObject private var appDelegate: MyAppDelegate

Now body will be called when the @Published var notificationStatus is changed.

For more info, see the docs https://developer.apple.com/documentation/swiftui/uiapplicationdelegateadaptor

If your app delegate conforms to the ObservableObject protocol, as in the example above, then SwiftUI puts the delegate it creates into the Environment. You can access the delegate from any scene or view in your app using the EnvironmentObject property wrapper: @EnvironmentObject private var appDelegate: MyAppDelegate This enables you to use the dollar sign ($) prefix to get a binding to published properties that you declare in the delegate. For more information, see projectedValue.

Upvotes: 0

Related Questions