iOS 15 UIWindowScene 无法正常工作

iOS 15 UIWindowScene not working properly

我想为 CarPlay 创建一个应用程序,不幸的是,缺乏教程让我很难创建一个没有任何功能的应用程序。当我想启动应用程序时出现问题,它指向 AppDelegate.swift 文件。我也设置了权利,所以它应该很好。 我该如何解决这个问题?

我对 UIWindowScene 有疑问(在我看来)。

AppDelegate

import UIKit
import CoreData
import CarPlay

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

    // MARK: UISceneSession Lifecycle
    @available(iOS 13.0, *)
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        
        return UISceneConfiguration(name: "CarPlay", sessionRole: connectingSceneSession.role)
    }
    
    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
 
    }

    // MARK: - Core Data stack

    lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "ev")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                 
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

    // MARK: - Core Data Saving support

    func saveContext () {
        let context = persistentContainer.viewContext
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }

}

场景代理

import UIKit
import CarPlay

@available(iOS 13.0, *)
class CarPlaySceneDelegate: UIResponder, UIWindowSceneDelegate, CPTemplateApplicationSceneDelegate {

    var interfaceController: CPInterfaceController?
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }
    }
    
    func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene,
        didConnect interfaceController: CPInterfaceController) {
        
        self.interfaceController = interfaceController
        
        let tabExample1 = CPListItem(text: "Example Column 1", detailText: "Example 1")
        let tabExample2 = CPListItem(text: "Example Column 2", detailText: "Example 2")
        let tabExample3 = CPListItem(text: "Example Column 3", detailText: "Example 3")
        let tabExample4 = CPListItem(text: "Example Column 4", detailText: "Example 4")
        
        let selectionItemsA = CPListSection(items: [tabExample1, tabExample2, tabExample3, tabExample4])
        let selectionItemsB = CPListSection(items: [tabExample1, tabExample3])
        
        let listTemplate = CPListTemplate(title: "", sections: [selectionItemsA])
        let listTemplateA = CPListTemplate(title: "", sections: [selectionItemsB])
        let listTemplateB = CPListTemplate(title: "", sections: [selectionItemsA])
        let listTemplateC = CPListTemplate(title: "", sections: [selectionItemsB])
        
        let tabA: CPListTemplate = listTemplate
        tabA.tabSystemItem = .favorites
        tabA.showsTabBadge = false
        
        let tabB: CPListTemplate = listTemplateA
        tabA.tabSystemItem = .mostRecent
        tabA.showsTabBadge = true
        
        let tabC: CPListTemplate = listTemplateB
        tabA.tabSystemItem = .history
        tabA.showsTabBadge = false
        
        let tabD: CPListTemplate = listTemplateC
        tabA.tabSystemItem = .search
        tabA.showsTabBadge = false
        
        let tabBarTemplate = CPTabBarTemplate(templates: [tabA, tabB, tabC, tabD])
        self.interfaceController?.setRootTemplate(tabBarTemplate, animated: true, completion: {_, _ in })
    }
    
    private func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene, didDisconnect interfaceController: CPInterfaceController) {
        self.interfaceController = nil
    }

    func sceneDidDisconnect(_ scene: UIScene) {

    }

    func sceneDidBecomeActive(_ scene: UIScene) {

    }

    func sceneWillResignActive(_ scene: UIScene) {

    }

    func sceneWillEnterForeground(_ scene: UIScene) {

    }

    func sceneDidEnterBackground(_ scene: UIScene) {
        (UIApplication.shared.delegate as? AppDelegate)?.saveContext()
    }

}

Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>UIApplicationSceneManifest</key>
    <dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <true/>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneClassName</key>
                    <string>CPTemplateApplicationScene</string>
                    <key>UISceneConfigurationName</key>
                    <string>CarPlay</string>
                    <key>UISceneDelegateClassName</key>
                    <string>$(PRODUCT_MODULE_NAME).CarPlaySceneDelegate</string>
                    <key>UISceneStoryboardFile</key>
                    <string>Main</string>
                </dict>
            </array>
        </dict>
    </dict>
</dict>
</plist>

错误

2021-10-06 12:16:22.750526+0200 ev[70981:3711041] *** Assertion failure in +[UIScene _sceneForFBSScene:create:withSession:connectionOptions:], UIScene.m:1148
2021-10-06 12:16:22.754761+0200 ev[70981:3711041] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'description specified a class of CPTemplateApplicationScene, but systemType UIWindowSceneSessionRoleApplication requires a minimum class of UIWindowScene'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff203fbbb4 __exceptionPreprocess + 242
    1   libobjc.A.dylib                     0x00007fff2019ebe7 objc_exception_throw + 48
    2   Foundation                          0x00007fff20750c12 _userInfoForFileAndLine + 0
    3   UIKitCore                           0x00007fff24387096 +[UIScene _sceneForFBSScene:create:withSession:connectionOptions:] + 2284
    4   UIKitCore                           0x00007fff24ffd75c -[UIApplication _connectUISceneFromFBSScene:transitionContext:] + 1253
    5   UIKitCore                           0x00007fff24ffdc0b -[UIApplication workspace:didCreateScene:withTransitionContext:completion:] + 289
    6   UIKitCore                           0x00007fff24a7e62e -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:] + 358
    7   FrontBoardServices                  0x00007fff26483d98 -[FBSScene _callOutQueue_agent_didCreateWithTransitionContext:completion:] + 419
    8   FrontBoardServices                  0x00007fff264b04a3 __94-[FBSWorkspaceScenesClient createWithSceneID:groupID:parameters:transitionContext:completion:]_block_invoke.180 + 102
    9   FrontBoardServices                  0x00007fff2649221a -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 209
    10  FrontBoardServices                  0x00007fff264b0082 __94-[FBSWorkspaceScenesClient createWithSceneID:groupID:parameters:transitionContext:completion:]_block_invoke + 352
    11  libdispatch.dylib                   0x000000010b3e7c0c _dispatch_client_callout + 8
    12  libdispatch.dylib                   0x000000010b3eab7f _dispatch_block_invoke_direct + 295
    13  FrontBoardServices                  0x00007fff264d6dc8 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 30
    14  FrontBoardServices                  0x00007fff264d6cbe -[FBSSerialQueue _targetQueue_performNextIfPossible] + 174
    15  FrontBoardServices                  0x00007fff264d6df0 -[FBSSerialQueue _performNextFromRunLoopSource] + 19
    16  CoreFoundation                      0x00007fff20369e25 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    17  CoreFoundation                      0x00007fff20369d1d __CFRunLoopDoSource0 + 180
    18  CoreFoundation                      0x00007fff20369254 __CFRunLoopDoSources0 + 340
    19  CoreFoundation                      0x00007fff20363951 __CFRunLoopRun + 875
    20  CoreFoundation                      0x00007fff20363103 CFRunLoopRunSpecific + 567
    21  GraphicsServices                    0x00007fff2c851cd3 GSEventRunModal + 139
    22  UIKitCore                           0x00007fff24ffbe63 -[UIApplication _run] + 928
    23  UIKitCore                           0x00007fff25000a53 UIApplicationMain + 101
    24  libswiftUIKit.dylib                 0x00007fff5933d052 $s5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGSgSSSgAJtF + 98
    25  ev                                  0x000000010b23cff8 $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 104
    26  ev                                  0x000000010b23cf87 $s2ev11AppDelegateC5$mainyyFZ + 39
    27  ev                                  0x000000010b23d108 main + 24
    28  dyld                                0x000000010b264e1e start_sim + 10
    29  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi: terminating with uncaught exception of type NSException
dyld4 config: DYLD_ROOT_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot DYLD_LIBRARY_PATH=/Users/coder/Library/Developer/Xcode/DerivedData/ev-gwuzkianekeqfaeltofdzmkuwodt/Build/Products/Debug-iphonesimulator:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libBacktraceRecording.dylib:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libMainThreadChecker.dylib:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib DYLD_FRAMEWORK_PATH=/Users/coder/Library/Developer/Xcode/DerivedData/ev-gwuzkianekeqfaeltofdzmkuwodt/Build/Products/Debug-iphonesimulator
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'description specified a class of CPTemplateApplicationScene, but systemType UIWindowSceneSessionRoleApplication requires a minimum class of UIWindowScene'
terminating with uncaught exception of type NSException
CoreSimulator 776.3 - Device: iPhone 11 (C3E67DA4-1F53-4110-B71D-41CA3646326D) - Runtime: iOS 15.0 (19A339) - DeviceType: iPhone 11
(lldb) 

显然,我在创建 info.plist

时犯了一个错误

当我将“UIWindowSceneSessionRoleApplication”替换为“CPTemplateApplicationSceneSessionRoleApplication”时,它确实加载了并且看起来不错