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”时,它确实加载了并且看起来不错
我想为 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”时,它确实加载了并且看起来不错