iOS13 sur Xcode 11 Écran noir même après avoir ajouté SceneDelegate et mis à jour Info.plist

10

Je reçois actuellement un écran vide avec Xcode 11, Target iOS 13.0 (l'application fonctionne bien avec toutes les versions ci-dessous iOS 12.1 à 12.4), je veux faire fonctionner mon application pour les utilisateurs iOS supérieurs à 12.1 et aussi 13.0 obtenir actuellement un écran vide malgré ajouter le SceneDelegate ci-dessous à mon projet existant et AppManifest

ajout d'un fichier manifeste d'application

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

Ce qui suit est mon AppDelegate qui est appelé en premier et exécute la didFinishLaunchWithOptionsméthode. Je veux savoir comment puis-je effectuer cet appel de méthode uniquement si mon ios cible est inférieur à 13.0 et appeler la méthode SceneDelegate pour initialiser mon rootViewController après 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
la source

Réponses:

28

Vous avez plusieurs problèmes ici. Il est important de lire la documentation relative au cycle de vie de l'application qui indique ce qui est appelé sous iOS 13 et ce qui est appelé sous iOS 12.

Vous pouvez également voir mon modèle d'application Single View qui prend en charge iOS 12 et 13.

En regardant votre code, voici un résumé des problèmes:

AppDelegate:

  • Vous ne devez configurer la fenêtre principale et le contrôleur de vue racine que si l'application est exécutée sous iOS 12 ou version antérieure. Vous devez vérifier cela lors de l'exécution.
  • La func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)méthode ne doit pas être dans le délégué d'application.
  • Pas directement lié mais ne dormez jamais au démarrage de l'application. Retirez la Thread.sleep(forTimeInterval: 3.0)ligne. Les utilisateurs veulent utiliser votre application, sans regarder l'écran de lancement plus longtemps que nécessaire. Et le blocage du fil principal au lancement de l'application peut entraîner la mort de votre application.

SceneDelegate:

  • C'est très bien, mais il n'y a aucune raison pour la guard let _ = (scene as? UIWindowScene) else { return }ligne, d'autant plus qu'elle est à l'intérieur d'unif let qui fait déjà ce contrôle.
  • Vous ne semblez pas utiliser SwiftUI, supprimez donc cette importation.

Je mettrais à jour votre délégué d'application pour qu'il ressemble davantage à ceci:

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

Votre délégué de scène pourrait ressembler à:

@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
la source
1
Merci beaucoup rmaddy. Appréciez vraiment votre temps et votre réponse. Malheureusement, après avoir apporté les modifications susmentionnées, je reçois toujours un écran vide :(
Kris RaduhaSt
Que se passe-t-il réellement dans votre code lors de l'exécution? Accédez au débogueur. Commencez avec un point d'arrêt dans la willConnectTométhode de délégué de scène et continuez pas à pas. Fait-il ce que vous attendez?
rmaddy
Rien ne se passe, je ne reçois aucun message d'erreur dans la console, je ne sais pas trop ce qui se passe, mais mon simulateur devient vide ... imgur.com/a/kip57Fg
Kris RaduhaSt
Est willConnectToappelé? Que se passe-t-il alors? At-il le point de créer et de configurer le contrôleur de vue racine? Encore une fois, parcourez le code avec le débogueur. Ne vous fiez pas seulement à la sortie de la console.
rmaddy
Oui, il est appelé et `window.rootViewController = newViewcontroller window.makeKeyAndVisible () 'cela a également été exécuté mais je vois un écran vide sur le simulateur iOS 11-13.0 mais quand je vais sur Target et que je passe à 12.1 au lieu de 13.0, l'application fonctionne correctement.
Kris RaduhaSt
12

Donc, étapes pour accéder à une version iOS 13 et inférieure

1) Changez la cible de déploiement en iOS 12.

2) Remplacez les méthodes d'AppDelegate par ce qu'elles devraient avoir pour le développement d'iOS 12. Ajoutez également ceci:

   var window: UIWindow?

3) Supprimez SceneDelegate.

4) Supprimez le manifeste de scène d'application dans votre info.plist.

Cela fonctionnera sur iOS 13 et la version iOS inférieure

Vinayak Bhor
la source
Ce doit être la meilleure réponse!
Swifty Codes
Meilleure réponse ....
Subrata Mondal
1

J'étais coincé avec ce problème, et finalement j'ai résolu de supprimer les références searchDisplayController du storyboard.

<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
la source
2
J'ai rencontré un problème similaire après avoir créé l'application pour iOS 13 avec Xcode 13. Mon application n'affichait qu'un écran noir après le LaunchScreen. Cela uniquement lors de l'installation à partir de Testflight. Le démarrage de l'application dans le simulateur ou avec un câble (schéma Debug and Release) commençait bien. Aussi iOS 12: problème du tout. Faire: 'grep -r -i' searchDisplayController 'a montré un texte similaire dans Main.storyboard. Après avoir supprimé ces lignes avec un éditeur de texte et recompilé dans Xcode 13, l'application démarre maintenant correctement sur iOS 13 installé à partir de TestFlight! Merci @Erick Martinez.
Rodge
j'ai ouvert la source de main.storyboard et ce searchDisplayController n'est plus là ..
timman
1

Lorsque j'ai eu un problème similaire, cela était dû au fait que le modèle d'application unique généré à l'aide de Xcode 11.0 était incompatible avec celui nécessaire pour une application construite avec Xcode 11.2.

J'ai donc créé une nouvelle application de page unique avec Xcode 11.2 et copié le SceneDelegate généré dans mon ancien projet qui a été créé à l'aide de Xcode 11.0.

Après cela, l'écran vide avait disparu et mon interface était à nouveau visible.

Diff

appleitung
la source
0

Suivez facilement ces étapes

1-) Supprimer le fichier délégué de scène

2-) Ajoutez le code ci-dessous à AppDelegate.swift

    class AppDelegate: UIResponder, UIApplicationDelegate {

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

3-) Supprimez la ligne du manifeste de la scène d'application de votre fichier .plist entrez la description de l'image ici

Emre Gürses
la source