从 SceneDelegate 获取 viewController 实例化的错误

Posted

技术标签:

【中文标题】从 SceneDelegate 获取 viewController 实例化的错误【英文标题】:getting bugs with viewController instantiation from SceneDelegate 【发布时间】:2021-02-27 23:01:57 【问题描述】:

所以我的目标是能够显示正确的 vc 而没有任何错误。这个问题实际上有多个错误。首先,显示代码块并先对其进行解释是有意义的,这样您就可以了解我在说什么。

在我的 SceneDelegate.swift willConnectTo() 方法中,我有这段代码......

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    self.window = self.window ?? UIWindow()

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let auth = Auth.auth()
    let actualuser = auth.currentUser
    


    auth.addStateDidChangeListener  (_, user) in
        
        if let user = user 
            
            db.document("student_users/\(actualuser?.uid)").getDocument  (docSnapshot, error) in
                if error != nil 
                    print("\(error)")
                 else 
                    guard let docSnap = docSnapshot?.exists else  return 
                    if docSnap == true 
                        let alreadyLoggedInAsAStudentViewController = storyboard.instantiateViewController(withIdentifier: Constants.StoryboardIDs.StudentEventDashboardStoryboardID) as! StudentSegmentedTableViewController
                        let navigationizedVC = UINavigationController(rootViewController: alreadyLoggedInAsAStudentViewController)
                        self.window!.rootViewController = navigationizedVC
                        self.window!.makeKeyAndVisible()
                     else 
                        let alreadyLoggedInAsASchoolViewController = storyboard.instantiateViewController(withIdentifier: Constants.StoryboardIDs.SchoolEventDashboardStoryboardID) as! SchoolTableViewController
                        let navigationizedSchoolVC = UINavigationController(rootViewController: alreadyLoggedInAsASchoolViewController)
                        self.window!.rootViewController = navigationizedSchoolVC
                        self.window!.makeKeyAndVisible()
                    
                
            
            
        
        
    
    
    guard let _ = (scene as? UIWindowScene) else  return 

所以在我的应用程序中,我有两种类型的用户,并且我使用了一些逻辑来实例化正确的 viewController。问题是这样的,假设我以学生身份登录,最小化模拟器窗口,然后重新运行模拟器,它显示错误的 vc,但是当我再次执行相同操作时,它显示正确的 vc。同样的事情也适用于其他用户。还有另一个错误,说用户已注销并且状态侦听器未激活,但是一旦我以学校用户身份登录,vcs 就会再次切换,但如果我重新运行模拟器,它显然会显示正确的 vc .

我在控制台中也遇到了这个错误,我查了一下,但我无法将我在其他问题中看到的内容应用到我的问题中。

这是问题的 gif。当我以学校用户身份登录时,您可以看到 vc 是如何出错的,但是当我最小化模拟器窗口并重新运行它时,会显示正确的 vc。只是想知道如何防止这种情况。谢谢

【问题讨论】:

【参考方案1】:

你需要像这样启动你的窗口:

guard let windowScene = (scene as? UIWindowScene) else  return 
let window = UIWindow(windowScene: windowScene)
self.window = window

仅在使用不带 sceneDelegate 的 appDelegate 时才建议实例化 UIWindow,这样可能会导致内存问题

另外,请记住,您在打开应用之前调用的是文档。因此,请检查变量 docSnap 是否第一次没有返回 false。也许就是这样。但是在你的代码中并不清楚哪个视图是哪个

【讨论】:

好吧好吧,问你几个问题。第一个问题,我在 appDelegate 中实例化窗口会防止内存问题吗?下一个问题,如何检查 docSnap 变量是否第一次返回 false?最后一个问题,我的代码的哪一部分不清楚?如果您愿意提供帮助,我会很乐意解释更多。 @Felipe Andrade 另外,如果它显示错误的视图,它很可能在第一次返回 false 时,那么我该如何防止这种情况呢?,我认为一个警卫语句可以完成工作,但我想我错了. @Felipe Andrade 检查正在发生的事情的最佳方法是使用断点。如果您单击文件上的行号,它将在运行期间停在那里。因此,之后您可以调用日志窗口po my variable 以了解发生了什么。你也可以在那里运行一些代码 我不确定去 appDelegate 是否能解决问题,但值得一试。您的代码非常适合工作代码,但我建议您在互联网上阅读有关 clean code 的内容

以上是关于从 SceneDelegate 获取 viewController 实例化的错误的主要内容,如果未能解决你的问题,请参考以下文章

从 Xcode 启动 App Clip 时未调用 SceneDelegate 的“继续”

如何从 XCUIApplication 对象访问当前的 SceneDelegate?

SwiftUI如何从视图调用或通知scenedelegate

从 iOS 11+ 项目中删除 SceneDelegate 的正确方法 - 应用程序中需要哪些代码(_:didFinishLaunchingWithOptions)

使用 SceneDelegate.toView() 弹出视图

如何从自定义 UITableViewCell 获取值到 ViewController?