2

我在我的场景委托中创建了一个环境对象,并且还想在驻留在我的场景委托中的另一个函数中使用它。代码如下所示:

SceneDelegate.swift

    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        var window: UIWindow?
        //@EnvironmentObject var data: DataFetcher
        var data = DataFetcher()
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
 
            if let windowScene = scene as? UIWindowScene {
                
                let window = UIWindow(windowScene: windowScene)
                let data = (UIApplication.shared.delegate as! AppDelegate).self.data
                window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(data))
                self.window = window
                window.makeKeyAndVisible()
            }
        }
        
        func handleIncomingDynamicLink(_ dynamicLink: DynamicLink){
            guard let url = dynamicLink.url else {
                print("That's weird. My dynamic link object has no url")
                return
            }
            print("Your incoming link parameter is \(url.absoluteString)")
            guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
                let queryItems = components.queryItems else {return}
            self.data.linkRecieved = true
            print(data.linkRecieved)
        }
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        if let incomingURL = userActivity.webpageURL {
            print("Incoming URL is \(incomingURL)")
            _ = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { (dynamicLink, error) in
                guard error == nil else{
                    print("Found an error! \(error!.localizedDescription)")
                    return
                }
                if let dynamicLink = dynamicLink {
                    self.handleIncomingDynamicLink(dynamicLink)
                }
            }
        }
    }
        

问题是在执行handleIncomingDynamicLink 函数时,环境对象的linkRecieved 变量在contentview 内没有改变(我已经验证该变量在函数运行后确实被更改为true)。非常感谢解决此问题的任何见解!

4

2 回答 2

2

您需要注入var data属性,因此删除以下行

let window = UIWindow(windowScene: windowScene)
//let data = (UIApplication.shared.delegate as! AppDelegate).self.data // << this one
window.rootViewController = UIHostingController(rootView: 
   ContentView().environmentObject(self.data))   // << inject own property
于 2020-10-24T18:39:15.753 回答
2

您已经为属性分配了一个DataFetcher实例data,大概是为了设置它的类型并消除您的属性未初始化的错误。

Then in willConnectTo you get the DataFetcher instance from your AppDelegate. Your dataproperty and the localdatavariable inwillConnectTo(That you subsequently add to the environment) now reference different instances ofDataFetcher`, but you didn't realise.

I am not a big fan of assigning "throw away" instances to properties for this reason.

A better approach is to use an implicitly unwrapped optional. That way if you don't assign a value to the property you will get a crash and quickly work out that something isn't right.

Then in willConectTo you can assign the instance from your AppDelegate to the property and put it in the environment.

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        var window: UIWindow?
        //@EnvironmentObject var data: DataFetcher
        var data: DataFetcher!
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
 
            if let windowScene = scene as? UIWindowScene {
                
                let window = UIWindow(windowScene: windowScene)
                self.data = (UIApplication.shared.delegate as! AppDelegate).self.data
                window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(data))
                self.window = window
                window.makeKeyAndVisible()
            }
        }
于 2020-10-30T20:47:52.277 回答