iOS13 en la pantalla negra de Xcode 11 incluso después de agregar SceneDelegate y actualizar Info.plist

10

Actualmente estoy obteniendo una pantalla en blanco con Xcode 11, Target iOS 13.0 (la aplicación funciona bien con todas las versiones siguientes iOS 12.1 hasta 12.4), quiero hacer que mi aplicación funcione para los usuarios de iOS por encima de 12.1 y también 13.0 actualmente obteniendo pantalla en blanco a pesar de agregando el siguiente SceneDelegate a mi proyecto existente y AppManifest

Agregar archivo de manifiesto de la aplicación

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

El siguiente es mi AppDelegate que se llama primero y ejecuta el didFinishLaunchWithOptionsmétodo. Quiero saber cómo puedo hacer que este método llame solo si mi Target ios es inferior a 13.0 y llamar al método SceneDelegate para inicializar mi rootViewController después de 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            
        }
    }
Kris RaduhaSt
fuente

Respuestas:

28

Tienes varios problemas aquí. Es importante leer la documentación relacionada con el ciclo de vida de la aplicación que establece lo que se llama en iOS 13 y lo que se llama en iOS 12.

También es posible que desee ver mi plantilla de aplicación de vista única que admite iOS 12 y 13.

Mirando su código, aquí hay un resumen de los problemas:

AppDelegate:

  • Solo debe configurar la ventana principal y el controlador de vista raíz si la aplicación se ejecuta con iOS 12 o anterior. Debe verificar esto en tiempo de ejecución.
  • El func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)método no debe estar en el delegado de la aplicación.
  • No está directamente relacionado, pero nunca duerme en el inicio de la aplicación. Eliminar la Thread.sleep(forTimeInterval: 3.0)línea. Los usuarios desean usar su aplicación, no mirar la pantalla de inicio más tiempo del necesario. Y bloquear el hilo principal en el inicio de la aplicación puede hacer que su aplicación sea eliminada.

SceneDelegate:

  • Esto está muy bien, pero no hay razón para la guard let _ = (scene as? UIWindowScene) else { return }línea, especialmente porque está dentro de una línea if letque ya hace esa verificación.
  • Parece que no estás usando SwiftUI, así que elimina esa importación.

Actualizaría su delegado de aplicaciones para que sea más parecido a esto:

@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.
    }
}

Su delegado de escena podría ser como:

@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
    }
}
rmaddy
fuente
1
Muchas gracias, rmaddy. Realmente aprecio tu tiempo y respuesta. Desafortunadamente, después de hacer los cambios antes mencionados, sigo teniendo una pantalla en blanco :(
Kris RaduhaSt
¿Qué sucede realmente en su código en tiempo de ejecución? Paso a paso con el depurador. Comience con un punto de interrupción en el willConnectTométodo de delegado de escena y vaya paso a paso. ¿Hace lo que esperas?
rmaddy
No pasa nada, no recibo ningún mensaje de error en la consola, no estoy seguro de lo que está sucediendo, pero mi simulador se queda en blanco ... imgur.com/a/kip57Fg
Kris RaduhaSt
Se willConnectTollama? Entonces que pasa? ¿Tiene el punto de crear y configurar el controlador de vista raíz? Nuevamente, recorra el código con el depurador. No solo confíe en la salida de la consola.
rmaddy
Sí, se llama y `window.rootViewController = newViewcontroller window.makeKeyAndVisible () 'también se ejecutó, pero veo una pantalla en blanco en el simulador iOS 11-13.0, pero cuando voy a Target y cambio a 12.1 en lugar de 13.0, la aplicación funciona bien.
Kris RaduhaSt
12

Entonces, los pasos para llegar a un iOS 13 y una versión inferior

1) Cambiar el objetivo de implementación a iOS 12.

2) Reemplace los métodos de AppDelegate con lo que deberían tener para el desarrollo de iOS 12. También agregue esto:

   var window: UIWindow?

3) Eliminar SceneDelegate.

4) Elimine Application Scene Manifest en su info.plist.

Funcionará tanto en iOS 13 como en versiones anteriores de iOS

Vinayak Bhor
fuente
¡Esta tiene que ser la mejor respuesta!
Códigos Swifty
La mejor respuesta ...
Subrata Mondal
1

Estaba atrapado con este problema y finalmente resolví eliminar las referencias de searchDisplayController del guión gráfico.

<searchDisplayController id="pWz-So-g6H">
                    <connections>
                        <outlet property="delegate" destination="Yci-sd-Mof" id="fjs-ah-jLs"/>
                        <outlet property="searchContentsController" destination="Yci-sd-Mof" id="gQN-1r-gti"/>
                        <outlet property="searchResultsDataSource" destination="Yci-sd-Mof" id="2Jf-lh-Ute"/>
                        <outlet property="searchResultsDelegate" destination="Yci-sd-Mof" id="Hap-SA-f02"/>
                    </connections>
                </searchDisplayController>
Erick Martinez
fuente
2
Tuve un problema similar después de compilar la aplicación para iOS 13 con Xcode 13. Mi aplicación solo mostraba una pantalla en negro después de LaunchScreen. Esto solo cuando se instala desde Testflight. Iniciar la aplicación en el simulador o con un cable (esquema de depuración y liberación) estaba comenzando bien. También iOS 12: problema en absoluto. Haciendo: 'grep -r -i' searchDisplayController 'mostró texto similar en Main.storyboard. Después de eliminar estas líneas con un editor de texto y volver a compilar en Xcode 13, ¡la aplicación ahora comienza bien en iOS 13 instalado desde TestFlight! Gracias @Erick Martinez.
Rodge
Abrí la fuente para main.storyboard y este searchDisplayController ya no está allí ...
timman
1

Cuando tuve un problema similar se debió a que la plantilla de aplicación única generada con Xcode 11.0 era incompatible con la que se necesita para una aplicación creada con Xcode 11.2.

Así que acabo de crear una nueva aplicación de una sola página con Xcode 11.2 y copié el SceneDelegate generado a mi antiguo proyecto que fue creado usando Xcode 11.0.

Después de eso, la pantalla en blanco había desaparecido y mi interfaz era visible una vez más.

Diferencia

appleitung
fuente
0

Sigue fácilmente estos pasos

1-) Eliminar el archivo delegado de escena

2-) Agregue el siguiente código a AppDelegate.swift

    class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        return true
    }
   }

3-) Elimine la línea del Manifiesto de la escena de aplicación de su archivo .plist ingrese la descripción de la imagen aquí

Emre Gürses
fuente