iOS13 su schermo nero Xcode 11 anche dopo aver aggiunto SceneDelegate e aver aggiornato Info.plist


10

Attualmente sto ottenendo uno schermo vuoto con Xcode 11, Target iOS 13.0 (l'app funziona bene con tutte le versioni precedenti iOS 12.1 fino a 12.4), voglio far funzionare la mia app per entrambi gli utenti iOS sopra la 12.1 e anche 13.0 attualmente sta ottenendo uno schermo vuoto nonostante aggiungendo il SceneDelegate di seguito al mio progetto esistente e AppManifest

aggiunta del file manifest dell'app

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

Quello che segue è il mio AppDelegate che viene chiamato per primo ed esegue il didFinishLaunchWithOptionsmetodo. Voglio sapere come posso chiamare questo metodo solo se il mio iOS ios è inferiore a 13.0 e chiamare il metodo SceneDelegate per inizializzare il mio rootViewController dopo la 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            
        }
    }

Risposte:


28

Hai diversi problemi qui. È importante leggere la documentazione relativa al ciclo di vita dell'app che indica ciò che viene chiamato in iOS 13 e ciò che viene chiamato in iOS 12.

Potresti anche voler vedere il mio modello di app a visualizzazione singola che supporta iOS 12 e 13.

Guardando il tuo codice, ecco un riepilogo dei problemi:

AppDelegate:

  • È necessario configurare la finestra principale e il controller della vista principale solo se l'app è in esecuzione su iOS 12 o versioni precedenti. Devi verificarlo in fase di esecuzione.
  • Il func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)metodo non dovrebbe essere nel delegato dell'app.
  • Non direttamente correlato ma non dormire mai all'avvio dell'app. Rimuovi la Thread.sleep(forTimeInterval: 3.0)linea. Gli utenti vogliono usare la tua app, non fissare la schermata di avvio più a lungo del necessario. E il blocco del thread principale all'avvio dell'app può causare la morte dell'app.

SceneDelegate:

  • Questo va per lo più bene ma non c'è motivo per la guard let _ = (scene as? UIWindowScene) else { return }linea, soprattutto perché è dentro un if letcontrollo che fa già quel controllo.
  • Sembra che non usi SwiftUI, quindi rimuovi tale importazione.

Vorrei aggiornare il delegato dell'app in modo che sia più simile a questo:

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

Il tuo delegato alla scena potrebbe essere come:

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

1
Grazie mille rmaddy. Apprezzo molto il tuo tempo e la tua risposta. Sfortunatamente, dopo aver apportato le modifiche di cui sopra ottengo ancora una schermata vuota :(
Kris Raduha,

Cosa succede realmente nel tuo codice in fase di esecuzione? Fai un passo avanti con il debugger. Inizia con un punto di interruzione nel willConnectTometodo delegato scena e procedi passo dopo passo. Fa quello che ti aspetti?
rmaddy,

Non succede nulla, non visualizzo alcun messaggio di errore nella console, non sono sicuro di cosa stia succedendo, ma il mio simulatore si svuota
Kris Raduha,

Si willConnectTochiama? Allora cosa succede? Ottiene il punto di creare e impostare il controller della vista principale? Ancora una volta, scorrere il codice con il debugger. Non basarti solo sull'output della console.
rmaddy,

Sì, si chiama e 'window.rootViewController = newViewcontroller window.makeKeyAndVisible ()' anche questo eseguito, ma vedo una schermata vuota sul simulatore iOS 11-13.0 ma quando vado su Target e cambio a 12.1 invece di 13.0 l'app funziona bene.
Kris Raduha,

12

Quindi passi per arrivare a iOS 13 e versioni precedenti

1) Cambia destinazione di distribuzione in iOS 12.

2) Sostituisci i metodi di AppDelegate con quelli che dovrebbero avere per lo sviluppo di iOS 12. Aggiungi anche questo:

   var window: UIWindow?

3) Rimuovere SceneDelegate.

4) Rimuovi Application Scene Manifest dal tuo info.plist.

Funzionerà su iOS 13 e versione iOS precedente


Questa deve essere la risposta migliore!
Codici Swifty

Migliore risposta ....
Subrata Mondal

1

Ero bloccato con questo problema e alla fine ho risolto la rimozione dei riferimenti searchDisplayController dallo 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>

2
Ho avuto un problema simile dopo aver creato l'app per iOS 13 con Xcode 13. La mia app mostrava solo una schermata nera dopo LaunchScreen. Questo solo quando si installa da Testflight. L'avvio dell'app nel simulatore o con un cavo (schema Debug and Release) stava iniziando bene. Anche iOS 12: problema a tutti. Fare: 'grep -r -i' searchDisplayController 'mostrava un testo simile in Main.storyboard. Dopo aver rimosso queste righe con un editor di testo e ricompilato in Xcode 13, l'app ora inizia bene su iOS 13 installato da TestFlight! Grazie @Erick Martinez.
Rodge,

ho aperto la fonte per main.storyboard e questo searchDisplayController non è più presente.
Timman,

1

Quando ho avuto un problema simile, ciò era dovuto al fatto che il modello Single-App generato utilizzando Xcode 11.0 era incompatibile con quello necessario per un'app creata con Xcode 11.2.

Così ho appena creato una nuova app a pagina singola con Xcode 11.2 e copiato lo SceneDelegate generato nel mio vecchio progetto creato con Xcode 11.0.

Dopodiché, lo schermo vuoto è diventato una mia interfaccia visibile ancora una volta.

diff


0

Mantieni facilmente questi passaggi

1-) Rimuovere il file delegato scena

2-) Aggiungi il codice seguente in AppDelegate.swift

    class AppDelegate: UIResponder, UIApplicationDelegate {

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

3-) Rimuovere la riga Manifest scena applicazione dal file .plist inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.