iOS13 trên Xcode 11 Màn hình đen ngay cả sau khi thêm SceneDelegate và cập nhật Info.plist


10

Tôi hiện đang có một màn hình trống với Xcode 11, Target iOS 13.0 (ứng dụng hoạt động tốt với tất cả các phiên bản dưới đây iOS 12.1 đến 12.4), tôi muốn làm cho Ứng dụng của mình hoạt động cho cả người dùng iOS trên 12.1 và 13.0 hiện đang có màn hình trống thêm Cảnh dưới đây vào dự án hiện tại của tôi và Ứng dụng

thêm tệp Bản kê khai ứng dụng

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

Sau đây là AppDelegate của tôi được gọi đầu tiên và thực thi didFinishLaunchWithOptionsphương thức. Tôi muốn biết làm thế nào tôi có thể thực hiện cuộc gọi phương thức này chỉ khi Target ios của tôi nhỏ hơn 13.0 và gọi phương thức SceneDelegate để khởi tạo rootViewControll của tôi sau 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            
        }
    }

Câu trả lời:


28

Bạn có một số vấn đề ở đây. Điều quan trọng là phải đọc tài liệu liên quan đến vòng đời ứng dụng, trong đó nêu rõ những gì được gọi trong iOS 13 và những gì được gọi trong iOS 12.

Bạn cũng có thể muốn xem mẫu Ứng dụng một lần xem của tôi hỗ trợ iOS 12 và 13.

Nhìn vào mã của bạn, đây là một bản tóm tắt các vấn đề:

Ứng viên:

  • Bạn chỉ nên thiết lập cửa sổ chính và trình điều khiển xem gốc nếu ứng dụng đang được chạy trong iOS 12 trở về trước. Bạn cần kiểm tra điều này trong thời gian chạy.
  • Các func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)phương pháp không phải ở trong các đại biểu ứng dụng.
  • Không liên quan trực tiếp nhưng không bao giờ ngủ khi khởi động ứng dụng. Bỏ Thread.sleep(forTimeInterval: 3.0)dòng. Người dùng muốn sử dụng ứng dụng của bạn, không nhìn chằm chằm vào màn hình khởi chạy lâu hơn mức cần thiết. Và việc chặn luồng chính khi khởi chạy ứng dụng có thể khiến ứng dụng của bạn bị giết.

CảnhDelegate:

  • Điều này chủ yếu là tốt nhưng không có lý do cho guard let _ = (scene as? UIWindowScene) else { return }dòng, đặc biệt là vì nó nằm trong một if letkiểm tra đã được thực hiện.
  • Bạn dường như không sử dụng SwiftUI để loại bỏ việc nhập đó.

Tôi sẽ cập nhật đại biểu ứng dụng của bạn để giống như thế này:

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

Đại biểu cảnh của bạn có thể giống như:

@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
Cảm ơn bạn rất nhiều rmaddy. Thực sự đánh giá cao thời gian và câu trả lời của bạn. Thật không may, sau khi thực hiện các thay đổi đã nói ở trên, tôi vẫn nhận được một màn hình trống :(
Kris RaduhaSt

Điều gì thực sự xảy ra trong mã của bạn khi chạy? Bước qua với trình gỡ lỗi. Bắt đầu với một điểm dừng trong willConnectTophương thức ủy nhiệm cảnh và đi từng bước một. Nó làm những gì bạn mong đợi?
rmaddy

Không có gì xảy ra tôi không nhận được bất kỳ thông báo lỗi nào trong bảng điều khiển không chắc chắn điều gì đang xảy ra nhưng trình giả lập của tôi bị trống ... imgur.com/a/kip57Fg
Kris RaduhaSt

Được willConnectTogọi là gì? Sau đó điều gì xảy ra? Liệu nó có nhận được điểm tạo và thiết lập bộ điều khiển xem gốc không? Một lần nữa, bước qua mã với trình gỡ lỗi. Đừng chỉ dựa vào đầu ra của bàn điều khiển.
rmaddy

Vâng, nó được gọi và `window.rootViewControll = newViewcontroll window.makeKeyAndVisible () 'này cũng được thực thi nhưng tôi thấy một màn hình trống trên trình giả lập iOS 11-13.0 nhưng khi tôi vào Target và thay đổi thành 12.1 thay vì 13.0 thì ứng dụng hoạt động tốt.
Kris RaduhaSt

12

Vì vậy, các bước để có được phiên bản iOS 13 trở xuống

1) Thay đổi mục tiêu triển khai sang iOS 12.

2) Thay thế các phương thức của AppDelegate bằng những gì họ cần có để phát triển iOS 12. Cũng thêm điều này:

   var window: UIWindow?

3) Xóa CảnhDelegate.

4) Xóa Bản kê khai cảnh ứng dụng trong thông tin của bạn.

Nó sẽ hoạt động trên cả iOS 13 và phiên bản iOS thấp hơn


Đây phải là câu trả lời tốt nhất!
Mã Swifty

Câu trả lời hay nhất ....
Subrata Mondal

1

Tôi đã bị mắc kẹt với vấn đề này và cuối cùng tôi đã giải quyết việc loại bỏ các tham chiếu searchDisplayControll khỏi bảng phân cảnh.

<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
Tôi gặp vấn đề tương tự sau khi xây dựng ứng dụng cho iOS 13 bằng Xcode 13. Ứng dụng của tôi chỉ hiển thị màn hình đen sau LaunchScreen. Điều này chỉ khi cài đặt từ Testflight. Bắt đầu ứng dụng trong trình giả lập hoặc bằng cáp (lược đồ Gỡ lỗi và Phát hành) đã bắt đầu tốt. Ngoài ra iOS 12: vấn đề nào cả. Đang làm: 'grep -r -i' searchDisplayContoder 'đã hiển thị văn bản tương tự trong Main.storyboard. Sau khi xóa các dòng này bằng trình soạn thảo văn bản và biên dịch lại trong Xcode 13, ứng dụng hiện đã khởi động tốt trên iOS 13 được cài đặt từ TestFlight! Cảm ơn @Erick Martinez.
Rodge

tôi đã mở nguồn cho main.storyboard và tìm kiếm nàyDisplayControll không còn ở đó nữa ..
timman

1

Khi tôi gặp vấn đề tương tự, đó là do mẫu Ứng dụng đơn được tạo bằng Xcode 11.0 không tương thích với ứng dụng cần thiết cho ứng dụng được xây dựng với Xcode 11.2.

Vì vậy, tôi vừa tạo một Ứng dụng một trang mới với Xcode 11.2 và sao chép SceneDelegate được tạo vào dự án cũ của tôi được tạo bằng Xcode 11.0.

Sau đó, màn hình trống đã biến mất một giao diện của tôi hiển thị một lần nữa.

Khác


0

Dễ dàng bỏ qua các bước này

1-) Xóa tập tin đại biểu cảnh

2-) Thêm mã dưới đây vào AppDelegate.swift

    class AppDelegate: UIResponder, UIApplicationDelegate {

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

3-) Xóa dòng Manifest của Application Application khỏi tệp .plist của bạn nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.