iOS13 na tela preta do Xcode 11 mesmo depois de adicionar o SceneDelegate e atualizar o Info.plist

10

No momento, estou recebendo uma tela em branco com o Xcode 11, Target iOS 13.0 (o aplicativo funciona bem com todas as versões abaixo do iOS 12.1 a 12.4), quero fazer meu aplicativo funcionar para usuários do iOS acima de 12.1 e também com a versão 13.0 atualmente recebendo a tela em branco, apesar de adicionando o SceneDelegate abaixo ao meu projeto existente e AppManifest

adicionando arquivo de manifesto do aplicativo

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

A seguir, meu AppDelegate, que está sendo chamado primeiro e executando o didFinishLaunchWithOptionsmétodo. Quero saber como posso fazer essa chamada de método apenas se meu ios de destino for menor que 13.0 e chamar o método SceneDelegate para inicializar meu rootViewController após a 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
fonte

Respostas:

28

Você tem vários problemas aqui. É importante ler a documentação relacionada ao ciclo de vida do aplicativo, que indica o que é chamado no iOS 13 e o que é chamado no iOS 12.

Você também pode querer ver meu modelo de aplicativo de visualização única que suporta iOS 12 e 13.

Olhando para o seu código, aqui está um resumo dos problemas:

AppDelegate:

  • Você só deve configurar a janela principal e o controlador de visualização raiz se o aplicativo estiver sendo executado no iOS 12 ou anterior. Você precisa verificar isso em tempo de execução.
  • O func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)método não deve estar no delegado do aplicativo.
  • Não está diretamente relacionado, mas nunca dorme na inicialização do aplicativo. Retire a Thread.sleep(forTimeInterval: 3.0)linha. Os usuários desejam usar seu aplicativo, não encaram a tela de inicialização por mais tempo que o necessário. E o bloqueio do encadeamento principal na inicialização do aplicativo pode causar a sua morte.

CenaDelegada:

  • Isso é bom, mas não há razão para a guard let _ = (scene as? UIWindowScene) else { return }linha, especialmente porque ela está dentro de uma if letque já faz essa verificação.
  • Você não parece estar usando o SwiftUI, então remova essa importação.

Eu atualizaria o delegado do seu aplicativo para ficar mais assim:

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

O delegado da cena pode 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
fonte
11
Muito obrigado rmaddy. Realmente aprecio seu tempo e resposta. Infelizmente, depois de fazer as alterações acima mencionadas eu ainda obter uma tela em branco :(
Kris RaduhaSt
O que realmente acontece no seu código em tempo de execução? Avance com o depurador. Comece com um ponto de interrupção no willConnectTométodo de delegação de cena e vá passo a passo. Faz o que você espera?
rmaddy
Nada acontece eu não receber quaisquer mensagens de erro no console não sei o que está acontecendo, mas meu simulador fica em branco ... imgur.com/a/kip57Fg
Kris RaduhaSt
É willConnectTochamado? Então o que acontece? Chega ao ponto de criar e configurar o controlador de visualização raiz? Novamente, percorra o código com o depurador. Não confie apenas na saída do console.
rmaddy
Sim, ele é chamado e `window.rootViewController = newViewcontroller window.makeKeyAndVisible () 'isso também é executado, mas eu vejo uma tela em branco no simulador do iOS 11-13.0, mas quando vou para o Target e mudo para 12.1 em vez de 13.0, o aplicativo funciona bem.
precisa saber é o seguinte
12

Portanto, as etapas para obter um iOS 13 e uma versão inferior

1) Altere o destino da implantação para o iOS 12.

2) Substitua os métodos do AppDelegate pelo que eles deveriam ter para o desenvolvimento do iOS 12. Adicione também:

   var window: UIWindow?

3) Remova o SceneDelegate.

4) Remova o manifesto da cena do aplicativo em seu info.plist.

Funcionará no iOS 13 e na versão iOS inferior

Vinayak Bhor
fonte
Essa deve ser a melhor resposta!
Swifty Codes
Melhor resposta ....
Subrata Mondal 23/04
1

Eu estava com esse problema e finalmente resolvi remover as referências searchDisplayController do 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
fonte
2
Eu tive um problema semelhante depois de criar o aplicativo para iOS 13 com o Xcode 13. Meu aplicativo só mostrava uma tela preta após o LaunchScreen. Isso somente ao instalar a partir do Testflight. Iniciar o aplicativo no simulador ou com um cabo (esquema Debug and Release) estava começando bem. Também iOS 12: problema. Fazendo: 'grep -r -i' searchDisplayController 'mostrou texto semelhante no Main.storyboard. Depois de remover essas linhas com um editor de texto e recompilar no Xcode 13, o aplicativo agora começa bem no iOS 13 instalado no TestFlight! Obrigado @Erick Martinez.
Rodge
Eu abri a fonte para main.storyboard e esta searchDisplayController não está mais lá ..
timman 03/04
1

Quando tive um problema semelhante, isso ocorreu porque o modelo de aplicativo único gerado usando o Xcode 11.0 era incompatível com o necessário para um aplicativo criado com o Xcode 11.2.

Então, acabei de criar um novo aplicativo de página única com o Xcode 11.2 e copiei o SceneDelegate gerado no meu projeto antigo, criado com o Xcode 11.0.

Depois disso, a tela em branco desapareceu e minha interface ficou visível mais uma vez.

Diff

appleitung
fonte
0

Siga estas etapas facilmente

1-) Remover arquivo delegado da cena

2-) Adicione o código abaixo ao AppDelegate.swift

    class AppDelegate: UIResponder, UIApplicationDelegate {

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

3-) Remova a linha Application manifest manifest do seu arquivo .plist insira a descrição da imagem aqui

Emre Gürses
fonte