SceneDelegateを追加してInfo.plistを更新した後でも、Xcode 11の黒い画面でiOS13


10

現在、Xcode 11、ターゲットiOS 13.0(アプリは12.4までのすべてのバージョンのiOS 12.1で正常に動作します)で空白の画面が表示されます。以下のSceneDelegateを既存のプロジェクトに追加し、 AppManifest

アプリマニフェストファイルの追加

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

以下は、最初に呼び出されてdidFinishLaunchWithOptionsメソッドを実行する私のAppDelegate です。Target iosが13.0未満の場合にのみこのメソッドを呼び出し、13.0以降にSceneDelegateメソッドを呼び出してrootViewControllerを初期化する方法を教えてください。

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

回答:


28

ここにはいくつかの問題があります。iOS 13で何が呼び出され、iOS 12で何が呼び出されるかを示すアプリのライフサイクルに関連するドキュメントを読むことが重要です。

また、iOS 12および13をサポートするシングルビューアプリテンプレート表示することもできます。

あなたのコードを見て、これが問題の要約です:

AppDelegate:

  • アプリがiOS 12以前で実行されている場合は、メインウィンドウとルートビューコントローラーのみをセットアップする必要があります。実行時にこれを確認する必要があります。
  • func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)この方法は、アプリデリゲートにすべきではありません。
  • 直接関係はありませんが、アプリの起動時にスリープ状態になることはありません。Thread.sleep(forTimeInterval: 3.0)行を削除します。ユーザーは、起動画面を必要以上に長く見つめるのではなく、アプリを使用したいと考えています。また、アプリの起動時にメインスレッドをブロックすると、アプリが強制終了される可能性があります。

SceneDelegate:

  • これはほとんど問題ありませんがguard let _ = (scene as? UIWindowScene) else { return }、特にif letそのチェックをすでに実行している内部にあるため、ラインに理由はありません。
  • SwiftUIを使用していないようなので、そのインポートを削除してください。

アプリのデリゲートを次のように更新します。

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

シーンデリゲートは次のようになります。

@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
本当にありがとうございました。あなたの時間と答えを本当に感謝します。残念ながら、前述の変更を行った後も、空白の画面が表示されます:(
Kris RaduhaSt

実行時にコードで実際に何が起こりますか?デバッガーをステップ実行します。willConnectToシーンデリゲートメソッドのブレークポイントから始めて、ステップごとに進みます。それはあなたが期待することをしますか?
rmaddy

何が起こっているのかコンソールでエラーメッセージが表示されないのですが、何が起こっているのかわかり
Kris RaduhaSt

されるwillConnectToと呼ばれますか?それから何が起こりますか?ルートビューコントローラーを作成および設定するポイントはありますか?もう一度、デバッガーでコードをステップ実行します。コンソール出力だけに頼らないでください。
rmaddy

はい、呼び出され、 `window.rootViewController = newViewcontroller window.makeKeyAndVisible() 'も実行されますが、iOS 11-13.0シミュレータで空白の画面が表示されますが、ターゲットに移動して13.0ではなく12.1に変更すると、アプリは正常に動作します。
Kris RaduhaSt

12

iOS 13以前のバージョンに到達するための手順

1)展開ターゲットをiOS 12に変更します。

2)AppDelegateのメソッドを、iOS 12の開発に必要なメソッドに置き換えます。これも追加してください:

   var window: UIWindow?

3)SceneDelegateを削除します。

4)info.plistからApplication Scene Manifestを削除します。

iOS 13以前のiOSバージョンで動作します


これが最良の答えでなければなりません!
スウィフティコード

ベストアンサー....
Subrata Mondal

1

私はこの問題に悩まされており、ストーリーボードからsearchDisplayController参照を削除することで解決しました。

<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
Xcode 13を使用してiOS 13用のアプリをビルドした後、同様の問題が発生しました。LaunchScreenの後にアプリに黒い画面しか表示されませんでした。これは、Testflightからインストールする場合のみです。シミュレーターまたはケーブル(スキームのデバッグとリリース)を使用してアプリを起動すると問題なく起動しました。また、iOS 12:全然問題。実行: 'grep -r -i' searchDisplayController 'はMain.storyboardに同様のテキストを表示しました。テキストエディターでこれらの行を削除し、Xcode 13で再コンパイルした後、TestFlightからインストールされたiOS 13でアプリが正常に起動します!@Erick Martinezに感謝します。
Rodge、

..私はmain.storyboardのソースを開いて、このsearchDisplayControllerはそこにはなくなりました
timman

1

私が同様の問題を抱えていたのは、Xcode 11.0を使用して生成されたシングルアプリテンプレートが、Xcode 11.2でビルドされたアプリに必要なものと互換性がないためでした。

そのため、Xcode 11.2で新しいシングルページアプリを作成し、生成されたSceneDelegateをXcode 11.0を使用して作成された古いプロジェクトにコピーしました。

その後、空白の画面は私のインターフェースがもう一度表示されなくなりました。

違い


0

これらの手順を簡単に休む

1-)シーンデリゲートファイルを削除する

2-)AppDelegate.swiftに以下のコードを追加します

    class AppDelegate: UIResponder, UIApplicationDelegate {

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

3-).plistファイルからApplication Scene Manifest行を削除します ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.