【问题标题】:Trying to access the environment object created inside scene delegate by another scenedelegate function试图访问由另一个场景委托函数在场景委托中创建的环境对象
【发布时间】:2020-10-17 15:48:47
【问题描述】:

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

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)。非常感谢解决此问题的任何见解!!!

【问题讨论】:

  • DataFetcherObservableObject 吗? linkReceived@Published 属性吗?
  • @NewDev 两者都是
  • 我看不懂(UIApplication.shared.delegate as! AppDelegate).self.data这行——为什么不是简单的self.data
  • @NewDev 允许在 appdelegate 中访问环境对象

标签: ios swiftui xcode12 environmentobject


【解决方案1】:

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

然后在willConnectTo 中,您会从您的AppDelegate. Your dataproperty and the localdatavariable inwillConnectTo(That you subsequently add to the environment) now reference different instances ofDataFetcher` 中获得DataFetcher 实例,但您没有意识到。

出于这个原因,我不太喜欢将“丢弃”实例分配给属性。

更好的方法是使用隐式展开的可选项。这样一来,如果您不为该属性分配值,您将遇到崩溃并迅速找出问题所在。

然后在willConectTo 中,您可以将AppDelegate 中的实例分配给属性并将其放入环境中。

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()
            }
        }

【讨论】:

    【解决方案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
    

    【讨论】:

    • 如果我删除该行,我不会失去对应用委托中环境对象的访问权限吗?
    • 什么意思?您会在问题中添加 AppDelegate 代码吗?
    猜你喜欢
    • 2021-11-14
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 2020-02-20
    • 2020-01-30
    • 1970-01-01
    相关资源
    最近更新 更多