Search code examples
core-dataios13appdelegateuiwindowuiscenedelegate

Setting Up CoreData with SceneDelegate - unknown identifier 'window' error - iOS 13 onwards


I was trying to use the official apple documentation for Core Data. Found here. I also ran into a question which was related to my issue, right here on stack.

I ran into an issue where, it kept saying that 'window' is not available in the context of AppDelegate. This is the very basic step as per the official documentation.

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {        
    if let rootVC = window?.rootViewController as? ViewController {
        rootVC.container = persistentContainer
    }        
    return true
}

How do I get past this?


Solution

  • The issue boils down to the changes, primarily, support for multiple scenes in iOS 13 and above. check this reddit link for the discussion.

    The solution is to move some of things from AppDelegate to SceneDelegate.

    Here is the final form of the essential parts of the above two classes.

    ----SceneDelegate

        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        self.window = UIWindow(windowScene: windowScene)
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        guard let rootVC = storyboard.instantiateViewController(identifier: "ViewController") as? ViewController else {
            print("ViewController not found")
            return
        }
        //set the storage here
        rootVC.container = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer
        //I dont want a  UI navigation controller.
        //let rootNC = UINavigationController(rootViewController: rootVC)
        //self.window?.rootViewController = rootNC
        //I want to use my basic view controller here. use rootNC to get a UI navigation controller
        self.window?.rootViewController = rootVC
        self.window?.makeKeyAndVisible()
    
    }
    

    --AppDelegate (remains unchanged )

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        //before iOS 13 you would be putting stuff here but not anymore.
        return true
    }
    

    Finally, you will leave the storage related code, where it was, in AppDelegate itself.