iOS13 บนหน้าจอ Xcode 11 Black แม้หลังจากเพิ่ม SceneDelegate และอัปเดต Info.plist


10

ขณะนี้ฉันกำลังรับหน้าจอว่างด้วย Xcode 11, Target iOS 13.0 (แอปทำงานได้ดีกับ iOS ทุกรุ่นที่ต่ำกว่า 12.1 จนถึง 12.4) ฉันต้องการให้แอปของฉันทำงานได้ทั้งผู้ใช้ iOS 12.1 ขึ้นไปและ 13.0 เพิ่ม SceneDelegate ด้านล่างให้กับโครงการที่มีอยู่ของฉันและ AppManifest

การเพิ่มไฟล์ Manifest ของแอพ

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

ต่อไปนี้คือ AppDelegate ของฉันซึ่งเรียกใช้ก่อนและดำเนินการตามdidFinishLaunchWithOptionsวิธี ฉันต้องการทราบว่าฉันจะทำให้วิธีการนี้เรียกได้อย่างไรถ้า Target ios ของฉันน้อยกว่า 13.0 และเรียกใช้เมธอด SceneDelegate เพื่อเริ่มต้น rootViewController ของฉันหลังจาก 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            
        }
    }

คำตอบ:


28

คุณมีปัญหาหลายประการที่นี่ สิ่งสำคัญคือการอ่านเอกสารที่เกี่ยวข้องกับวงจรชีวิตของแอพซึ่งระบุสิ่งที่เรียกว่าภายใต้ iOS 13 และสิ่งที่เรียกว่าภายใต้ iOS 12

คุณอาจต้องการเห็นเทมเพลตแอพ Single Viewของฉันที่รองรับ 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
ขอบคุณมาก rmaddy ขอบคุณเวลาและคำตอบของคุณจริงๆ น่าเสียดายหลังจากทำการเปลี่ยนแปลงดังกล่าวแล้วฉันยังคงได้รับหน้าจอว่างเปล่า :(
Kris RaduhaSt

เกิดอะไรขึ้นในรหัสของคุณขณะใช้งานจริง ผ่านขั้นตอนการดีบักเกอร์ เริ่มต้นด้วยจุดพักในwillConnectToวิธีการมอบหมายฉากและไปทีละขั้นตอน มันทำในสิ่งที่คุณคาดหวังหรือไม่?
rmaddy

ไม่มีอะไรเกิดขึ้นฉันไม่ได้รับข้อความแสดงข้อผิดพลาดในคอนโซลไม่แน่ใจว่าเกิดอะไรขึ้น แต่ตัวจำลองของฉันว่างเปล่า ... imgur.com/a/kip57Fg
Kris RaduhaSt

จะถูกwillConnectToเรียกว่า? ถ้าเช่นนั้นจะเกิดอะไรขึ้น? มันเป็นจุดของการสร้างและการตั้งค่าตัวควบคุมมุมมองรากหรือไม่? อีกครั้งผ่านรหัสกับดีบักเกอร์ อย่าพึ่งเพียงเอาท์พุทของคอนโซล
rmaddy

ใช่มันถูกเรียกและ `window.rootViewController = newViewcontroller window.makeKeyAndVisible () 'มันยังทำงานอยู่ แต่ฉันเห็นหน้าจอว่างเปล่าในโปรแกรมจำลอง iOS 11-13.0 แต่เมื่อฉันไปที่ Target และเปลี่ยนเป็น 12.1 แทนที่จะเป็น 13.0 แอปทำงานได้ดี
Kris RaduhaSt

12

ดังนั้นขั้นตอนในการเข้าถึง iOS 13 และเวอร์ชั่นต่ำกว่า

1) เปลี่ยนเป้าหมายการปรับใช้เป็น iOS 12

2) แทนที่วิธีของ AppDelegate ด้วยสิ่งที่ควรมีสำหรับการพัฒนา iOS 12 เพิ่มสิ่งนี้ด้วย:

   var window: UIWindow?

3) ลบ SceneDelegate

4) ลบแอปพลิเคชั่น Scene Manifest ใน info.plist ของคุณ

มันจะทำงานได้ทั้ง iOS 13 และ iOS เวอร์ชันต่ำกว่า


นี่จะเป็นคำตอบที่ดีที่สุด!
Swifty Codes

คำตอบที่ดีที่สุด ....
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
ฉันมีปัญหาที่คล้ายกันหลังจากสร้างแอพสำหรับ iOS 13 ด้วย Xcode 13 แอพของฉันแสดงเฉพาะหน้าจอสีดำหลังจาก LaunchScreen สิ่งนี้เฉพาะเมื่อติดตั้งจาก Testflight การเริ่มต้นแอพในตัวจำลองหรือด้วยสายเคเบิล (การดีบั๊กและการวางจำหน่าย) เริ่มต้นได้ดี นอกจากนี้ iOS 12: ปัญหาทั้งหมด การทำ: 'grep -r -i' searchDisplayController 'แสดงข้อความที่คล้ายกันใน Main.storyboard หลังจากลบบรรทัดเหล่านี้ด้วย text-editor และคอมไพล์ใหม่ใน Xcode 13 ตอนนี้แอปเริ่มต้นได้ดีบน iOS 13 ที่ติดตั้งจาก TestFlight! ขอบคุณ @Erick Martinez
Rodge

ผมเปิดแหล่งที่มาสำหรับ main.storyboard และ searchDisplayController นี้ไม่ได้อยู่ในที่นั่น ..
timman

1

เมื่อฉันมีปัญหาที่คล้ายกันเกิดจากเทมเพลตแอปเดียวที่สร้างขึ้นโดยใช้ Xcode 11.0 ไม่เข้ากันกับสิ่งที่จำเป็นสำหรับแอปที่สร้างด้วย Xcode 11.2

ดังนั้นฉันเพิ่งสร้าง Single-Page-App ใหม่ด้วย Xcode 11.2 และคัดลอก SceneDelegate ที่สร้างขึ้นไปยังโครงการเก่าของฉันซึ่งสร้างโดยใช้ Xcode 11.0

หลังจากนั้นหน้าจอว่างก็หายไปเป็นส่วนต่อประสานของฉันที่มองเห็นได้อีกครั้ง

diff


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-) ลบบรรทัด Application Scene Manifest ออกจากไฟล์. plist ของคุณ ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.