iOS13 on Xcode 11 Black screen even after adding SceneDelegate and updating Info.plist

Kri*_*aSt 4 xcode ios appdelegate swift ios13

I am currently getting a blank screen with Xcode 11, Target iOS 13.0 (the app works fine with all below versions iOS 12.1 till 12.4), I want to make my App work for both iOS users above 12.1 and also 13.0 currently getting blank screen despite adding the below SceneDelegate to my existing project and AppManifest

adding App Manifest file

import UIKit
    import SwiftUI

    @available(iOS 13.0, *)
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {

        var window: UIWindow?

        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

            //guard let _ = (scene as? UIWindowScene) else { return }

            let user  = UserDefaults.standard.object(forKey: "defaultsuserid")

            let userSelfIdent  = UserDefaults.standard.object(forKey: "userinitialident")

            if let windowScene = scene as? UIWindowScene {

                let internalWindow = UIWindow(windowScene: windowScene)

                if (user != nil && userSelfIdent != nil){
                     let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
                     let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
                        internalWindow.rootViewController = newViewcontroller
                        self.window = internalWindow
                        internalWindow.makeKeyAndVisible()
                }else {

                    guard let _ = (scene as? UIWindowScene) else { return }
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

The following is my AppDelegate which is getting called first and executing the didFinishLaunchWithOptions method. I want to know how can i make this method call only if my Target ios is less than 13.0 and call SceneDelegate method to initialize my rootViewController after 13.0?

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    @available(iOS 13.0, *)
    func application(_ application: UIApplication,
                     configurationForConnecting connectingSceneSession: UISceneSession,
                     options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    @available(iOS 13.0, *)
    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {

    }



    @available(iOS 13.0, *)
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        guard let _ = (scene as? UIWindowScene) else { return }

        if (user != nil && userSelfIdent != nil){

              let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
              let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
                self.window?.rootViewController = newViewcontroller
        }
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        Thread.sleep(forTimeInterval: 3.0)

        UINavigationBar.appearance().barTintColor = UIColor(red:0.08, green:0.23, blue:0.62, alpha:1.0)

        if (user != nil && userSelfIdent != nil){

              let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
              let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
                self.window?.rootViewController = newViewcontroller
        }

        return true
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

        let defaultUserID = UserDefaults.standard.string(forKey: "defaultUserID")


    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        switch (application.applicationState) {
        case UIApplicationState.active:
            do something

        case UIApplicationState.background, UIApplicationState.inactive:

            let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let newViewcontroller = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
            self.window?.rootViewController = newViewcontroller            
        }
    }
Run Code Online (Sandbox Code Playgroud)

Vin*_*hor 31

iOS 13及更低版本运行步骤:

  1. 将部署目标更改为 iOS 12。

  2. 将 AppDelegate 的方法替换为 iOS 12 开发应具备的方法。还要添加这个:

    var window: UIWindow?
    
    Run Code Online (Sandbox Code Playgroud)
  3. 删除场景委托。

  4. 删除 info.plist 中的应用程序场景清单。

它适用于 iOS 13 和更低的 iOS 版本


rma*_*ddy 14

您这里有几个问题。阅读与应用程序生命周期相关的文档非常重要,该文档阐明了iOS 13下的内容以及iOS 12下的内容。

您可能还需要查看支持iOS 12和13的我的Single View App模板

查看您的代码,这是问题的摘要:

AppDelegate:

  • 如果应用程序在iOS 12或更早版本下运行,则仅应设置主窗口和根视图控制器。您需要在运行时检查。
  • func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)方法不应在应用程序委托中。
  • 没有直接关系,但从不休眠应用程序启动。删除Thread.sleep(forTimeInterval: 3.0)线。用户想要使用您的应用程序,而不是盯着启动屏幕停留超过必要的时间。并且在应用启动时阻止主线程可能导致您的应用被杀死。

SceneDelegate:

  • 这通常很好,但是没有guard let _ = (scene as? UIWindowScene) else { return }必要使用该行,尤其是因为它位于if let已经进行了该检查的内部。
  • 您似乎没有使用SwiftUI,因此请删除该导入。

我将更新您的应用程序委托,使其更像这样:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        UINavigationBar.appearance().barTintColor = UIColor(red:0.08, green:0.23, blue:0.62, alpha:1.0)

        if #available(iOS 13.0, *) {
            // In iOS 13 setup is done in SceneDelegate
        } else {
            let window = UIWindow(frame: UIScreen.main.bounds)
            self.window = window

            if (user != nil && userSelfIdent != nil){
                let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
                let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
                window.rootViewController = newViewcontroller
            }
        }

        return true
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        if #available(iOS 13.0, *) {
            // In iOS 13 setup is done in SceneDelegate
        } else {
            self.window?.makeKeyAndVisible()
        }

        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Not called under iOS 13 - See SceneDelegate sceneWillResignActive
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Not called under iOS 13 - See SceneDelegate sceneDidEnterBackground
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Not called under iOS 13 - See SceneDelegate sceneWillEnterForeground
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Not called under iOS 13 - See SceneDelegate sceneDidBecomeActive
    }

    // MARK: UISceneSession Lifecycle

    @available(iOS 13.0, *)
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    @available(iOS 13.0, *)
    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }
}
Run Code Online (Sandbox Code Playgroud)

您的场景代表可能像:

@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }

        let window = UIWindow(windowScene: windowScene)
        self.window = window

        if (user != nil && userSelfIdent != nil){
            let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
            window.rootViewController = newViewcontroller
            window.makeKeyAndVisible()
        }
    }

    func sceneDidDisconnect(_ scene: UIScene) {
        // Called as the scene is being released by the system.
    }

    func sceneDidBecomeActive(_ scene: UIScene) {
        // Not called under iOS 12 - See AppDelegate applicationDidBecomeActive
    }

    func sceneWillResignActive(_ scene: UIScene) {
        // Not called under iOS 12 - See AppDelegate applicationWillResignActive
    }

    func sceneWillEnterForeground(_ scene: UIScene) {
        // Not called under iOS 12 - See AppDelegate applicationWillEnterForeground
    }

    func sceneDidEnterBackground(_ scene: UIScene) {
        // Not called under iOS 12 - See AppDelegate applicationDidEnterBackground
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢你,马迪。非常感谢您的时间和回答。不幸的是,进行上述更改后我仍然得到一个空白屏幕:( (4认同)
  • 如果你搞砸了一次并且它已经安装在模拟器中,即使你的设置正确,每次新启动仍然会是错误的......我终于通过删除应用程序并重新安装解决了我的问题,现在它终于再次工作了。疯狂的。 (4认同)

Bob*_*aaf 6

接受的答案在很多方面都是正确的,但我相信这不是一个完整的答案。我发布了一条评论,已经帮助几个人完全解决了这个问题,所以我也将其发布为答案:

如果你搞砸了一次并且它已经安装在模拟器中,那么每次新启动仍然会遇到这个问题,即使你的设置是正确的......

解决方案是删除该应用程序并使用正确的代码重新安装!这是一个疯狂的修复,但它有效!


Emr*_*ses 5

轻松按照以下步骤操作:

  1. 删除场景委托文件

  2. 将以下代码添加到 AppDelegate.swift

     class AppDelegate: UIResponder, UIApplicationDelegate {
    
     var window: UIWindow?
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
         return true
     }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 从 .plist 文件中删除 Application Scene Manifest 行

    删除场景清单