iOS13 auf Xcode 11 Schwarzer Bildschirm, auch nachdem SceneDelegate hinzugefügt und Info.plist aktualisiert wurde

10

Ich erhalte derzeit einen leeren Bildschirm mit Xcode 11, Target iOS 13.0 (die App funktioniert einwandfrei mit allen unten aufgeführten Versionen iOS 12.1 bis 12.4). Ich möchte, dass meine App sowohl für iOS-Benutzer über 12.1 als auch für 13.0 funktioniert, obwohl derzeit ein leerer Bildschirm angezeigt wird Hinzufügen des folgenden SceneDelegate zu meinem bestehenden Projekt und AppManifest

Hinzufügen einer App Manifest-Datei

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

Das Folgende ist mein AppDelegate, das zuerst aufgerufen wird und die didFinishLaunchWithOptionsMethode ausführt . Ich möchte wissen, wie ich diese Methode nur aufrufen kann, wenn mein Ziel-iOS kleiner als 13.0 ist, und die SceneDelegate-Methode aufrufen kann, um meinen rootViewController nach 13.0 zu initialisieren.

@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
quelle

Antworten:

28

Sie haben hier mehrere Probleme. Es ist wichtig, die Dokumentation zum App-Lebenszyklus zu lesen, in der angegeben ist, was unter iOS 13 und was unter iOS 12 genannt wird.

Möglicherweise möchten Sie auch meine Single View App-Vorlage anzeigen , die iOS 12 und 13 unterstützt.

Wenn Sie sich Ihren Code ansehen, finden Sie hier eine Zusammenfassung der Probleme:

AppDelegate:

  • Sie sollten das Hauptfenster und den Root View Controller nur einrichten, wenn die App unter iOS 12 oder früher ausgeführt wird. Sie müssen dies zur Laufzeit überprüfen.
  • Die func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)Methode sollte nicht im App-Delegaten enthalten sein.
  • Nicht direkt verwandt, aber niemals beim Start der App schlafen. Entfernen Sie die Thread.sleep(forTimeInterval: 3.0)Leitung. Benutzer möchten Ihre App verwenden und nicht länger als nötig auf den Startbildschirm starren. Das Blockieren des Hauptthreads beim Start der App kann dazu führen, dass Ihre App beendet wird.

SceneDelegate:

  • Dies ist meistens in Ordnung, aber es gibt keinen Grund für die guard let _ = (scene as? UIWindowScene) else { return }Leitung, zumal sie sich in einer befindet if let, die diese Prüfung bereits durchführt.
  • Sie scheinen SwiftUI nicht zu verwenden, entfernen Sie also diesen Import.

Ich würde Ihren App-Delegaten so aktualisieren, dass er eher so aussieht:

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

Ihr Szenendelegierter könnte sein wie folgt:

@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
quelle
1
Vielen Dank rmaddy. Schätzen Sie wirklich Ihre Zeit und Antwort. Leider bekomme ich nach den oben genannten Änderungen immer noch einen leeren Bildschirm :(
Kris RaduhaSt
Was passiert eigentlich in Ihrem Code zur Laufzeit? Treten Sie mit dem Debugger durch. Beginnen Sie mit einem Haltepunkt in der willConnectToSzenendelegatmethode und gehen Sie Schritt für Schritt vor. Tut es das, was Sie erwarten?
rmaddy
Nichts passiert Ich bekomme keine Fehlermeldungen in der Konsole, bin mir nicht sicher, was los ist, aber mein Simulator ist leer ... imgur.com/a/kip57Fg
Kris RaduhaSt
Wird willConnectTogerufen? Was passiert dann? Ist es sinnvoll, den Root-View-Controller zu erstellen und festzulegen? Gehen Sie den Code erneut mit dem Debugger durch. Verlassen Sie sich nicht nur auf die Konsolenausgabe.
rmaddy
Ja, es heißt und "window.rootViewController = newViewcontroller window.makeKeyAndVisible ()" wird ebenfalls ausgeführt, aber ich sehe einen leeren Bildschirm im iOS 11-13.0-Simulator, aber wenn ich zu Target gehe und zu 12.1 anstelle von 13.0 wechsle, funktioniert die App einwandfrei.
Kris RaduhaSt
12

Also Schritte zu einer iOS 13 und niedrigeren Version

1) Ändern Sie das Bereitstellungsziel in iOS 12.

2) Ersetzen Sie die Methoden von AppDelegate durch die Methoden, die sie für die Entwicklung von iOS 12 benötigen. Fügen Sie auch Folgendes hinzu:

   var window: UIWindow?

3) Entfernen Sie SceneDelegate.

4) Entfernen Sie das Anwendungsszenenmanifest in Ihrer info.plist.

Es funktioniert sowohl mit iOS 13 als auch mit einer niedrigeren iOS-Version

Vinayak Bhor
quelle
Das muss die beste Antwort sein!
Swifty Codes
Beste Antwort ....
Subrata Mondal
1

Ich war mit diesem Problem festgefahren und schließlich löste ich das Entfernen der searchDisplayController-Referenzen aus dem 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
quelle
2
Ich hatte ein ähnliches Problem, nachdem ich die App für iOS 13 mit Xcode 13 erstellt hatte. Meine App zeigte erst nach dem LaunchScreen einen schwarzen Bildschirm an. Dies nur bei der Installation von Testflight. Das Starten der App im Simulator oder mit einem Kabel (Schema Debug and Release) lief einwandfrei. Auch iOS 12: Problem überhaupt. Dabei: 'grep -r -i' searchDisplayController 'zeigte einen ähnlichen Text in Main.storyboard. Nachdem diese Zeilen mit einem Texteditor entfernt und in Xcode 13 neu kompiliert wurden, startet die App nun problemlos unter iOS 13, das von TestFlight installiert wurde! Danke @Erick Martinez.
Rodge
Ich habe die Quelle für main.storyboard geöffnet und dieser searchDisplayController ist nicht mehr da.
timman
1

Wenn ich ein ähnliches Problem hatte, lag es daran, dass die mit Xcode 11.0 generierte Single-App-Vorlage nicht mit der für eine mit Xcode 11.2 erstellte App benötigten Vorlage kompatibel war.

Also habe ich gerade eine neue Single-Page-App mit Xcode 11.2 erstellt und das generierte SceneDelegate in mein altes Projekt kopiert, das mit Xcode 11.0 erstellt wurde.

Danach war der leere Bildschirm verschwunden und meine Benutzeroberfläche wieder sichtbar.

Diff

appleitung
quelle
0

Brach diese Schritte leicht

1-) Entfernen Sie die Szenendelegatdatei

2-) Fügen Sie den folgenden Code zu AppDelegate.swift hinzu

    class AppDelegate: UIResponder, UIApplicationDelegate {

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

3-) Entfernen Sie die Zeile Application Scene Manifest aus Ihrer .plist-Datei Geben Sie hier die Bildbeschreibung ein

Emre Gürses
quelle