SceneDelegate를 추가하고 Info.plist를 업데이트 한 후에도 Xcode 11 검은 색 화면의 iOS13


10

현재 Xcode 11, Target iOS 13.0 (앱이 iOS 12.1에서 12.4 이하의 모든 버전에서 잘 작동 함)으로 빈 화면이 표시됩니다 .12.1 이상의 iOS 사용자 모두에게 앱을 작동시키고 싶습니다. 아래의 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 }
                }
            }
        }

다음은 내 AppDelegate이며 먼저 호출되어 didFinishLaunchWithOptions메소드를 실행합니다 . Target ios가 13.0보다 작은 경우에만이 메소드를 호출하고 13.0 이후에 rootViewController를 초기화하기 위해 SceneDelegate 메소드를 호출하는 방법을 알고 싶습니다.

@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을 지원하는 내 Single View App 템플릿 을보고 싶을 수도 있습니다 .

코드를 살펴보면 다음과 같은 문제가 요약되어 있습니다.

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
너무 많이 감사합니다. 시간과 답변에 진심으로 감사드립니다. 불행하게도, 상기 변경 후 난 여전히 빈 화면 :( 얻을
크리스 RaduhaSt

런타임에 코드에서 실제로 어떤 일이 발생합니까? 디버거를 단계별로 실행하십시오. willConnectTo장면 위임 방법 에서 중단 점으로 시작하여 단계별로 진행하십시오. 기대하는대로합니까?
rmaddy

아무것도 내가하지 있는지에가는하지만 내 시뮬레이터가 비어가는 무슨 ... 콘솔에서 오류 메시지를 얻을하지 않습니다 발생하지 imgur.com/a/kip57Fg
크리스 RaduhaSt

인가 willConnectTo라고? 그러면 어떻게됩니까? 루트 뷰 컨트롤러를 만들고 설정하는 것이 중요하지 않습니까? 다시, 디버거로 코드를 단계별로 실행하십시오. 콘솔 출력에만 의존하지 마십시오.
rmaddy

그렇습니다 .'window.rootViewController = newViewcontroller window.makeKeyAndVisible () '도 실행되었지만 iOS 11-13.0 시뮬레이터에서 빈 화면이 표시되지만 대상으로 이동하고 13.0 대신 12.1로 변경하면 앱이 제대로 작동합니다.
Kris RaduhaSt 1

12

iOS 13 이하 버전으로 이동하는 단계

1) 배포 대상을 iOS 12로 변경하십시오.

2) AppDelegate의 메소드를 iOS 12 개발에 필요한 것으로 바꿉니다. 또한 이것을 추가하십시오 :

   var window: UIWindow?

3) SceneDelegate를 제거하십시오.

4) info.plist에서 Application Scene Manifest를 제거하십시오.

iOS 13 이하의 iOS 버전 모두에서 작동합니다.


이것이 가장 좋은 답변이어야합니다!
Swifty 코드

최고의 답변 ....
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 2011

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.