4

I have a class :

class AppInfos_M: ObservableObject {
    @Published var currentUser: User_M = User_M()
    @Published var userTo: User_M = User_M()
}

I declare it in main and pass in to my view with environmentObject:

...

@main
struct TestApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
...

    @StateObject var appInfos_M = AppInfos_M()
    
    var body: some Scene {
        WindowGroup {
            LaunchScreen_V()
                .environmentObject(appInfos_M)
...
 
        }
    }
}

The class works very good in my app. Now I need to modify it from AppDelegate, because I need to get appInfos_M.userTo.id when I get a notification. I tried several things, but none works. How can I access it?

In all my views where I need it, I declare this way and it works fine, but not in AppDelegate, why?:

 @EnvironmentObject var appInfos_M: AppInfos_M

Here is one of the tests I tried that did not work:

...

class AppDelegate: NSObject, UIApplicationDelegate { ... }

...

@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {

...

func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {

@EnvironmentObject var appInfos_M: AppInfos_M

 let userInfo = response.notification.request.content.userInfo

appInfos_M.userTo.id = "just for testing here" // <- i get this error : Thread 1: Fatal error: No ObservableObject of type AppInfos_M found. A View.environmentObject(_:) for AppInfos_M may be missing as an ancestor of this view.

...

Note that 3 small dots ... replace any code that is useless here.

2
  • Does this answer your question stackoverflow.com/a/64484944/12299030? Commented Jan 22, 2022 at 18:34
  • 1
    You can't access the environment from your app delegate; the environment is only available from the view hierarchy. You can simply create a property in your app delegate adapter and assign your value to it Commented Jan 22, 2022 at 21:05

1 Answer 1

7

You can always store AppInfos_M in your AppDelegate Like this

class AppDelegate: NSObject, UIApplicationDelegate {
    var appInfos = AppInfos_M()
    (...)
}

You can then use it as EnvironmentObject as:

...
@main
struct TestApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
...
    
    var body: some Scene {
        WindowGroup {
            LaunchScreen_V()
                .environmentObject(appDelegate.appInfos)
...
 
        }
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

This should be marked as the answer. It worked for me w/out having to use a singleton as many of the other posts did.
I was about to refactor my code to use a singleton, until I found this! Perfect solution! Why some basic stuff has to be so complicated or overlooked in SwiftUI?
Happy to help :-) I definitely struggled with these things when I started doing iOS development in SwifUI without prior UIKit knowledge

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.