我有一个旧的(Objective-C)iOS 应用程序,我扩展到 Mac Catalyst,现在我想在不影响 iOS 版本的情况下为 Mac 版本添加多窗口支持。根据几个教程(示例),我设置了一个SceneDelegate
这样的......
@implementation SceneDelegate
#if TARGET_OS_MACCATALYST
@synthesize window;
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
if ([scene isKindOfClass:[UIWindowScene class]]) {
self.window = [[UIWindow alloc] initWithWindowScene:(UIWindowScene *)scene];
self.window.rootViewController = [[MainView alloc] init];
[self.window makeKeyAndVisible];
}
}
@end
#endif
...将此添加到 AppDelegate ...
#if TARGET_OS_MACCATALYST
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(nonnull UISceneSession *)connectingSceneSession options:(nonnull UISceneConnectionOptions *)options {
return [[UISceneConfiguration alloc] initWithName:@"Main" sessionRole:connectingSceneSession.role];
}
#endif
...并将其添加到 Info.plist:
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
</dict>
<key>UIApplicationSceneManifest-macos</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Main</string>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneDelegateClassName</key>
<string>SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
我仍在AppDelegate
'application:didFinishLaunchingWithOptions:
方法中进行大量设置,但从未调用过该方法,也从未调用过,application:configurationForConnectingSceneSession:options:
并且控制台中没有错误。于是我把场景的定义从Info.plist文件移到了application:configurationForConnectingSceneSession:options:
方法中,像这样……
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(nonnull UISceneSession *)connectingSceneSession options:(nonnull UISceneConnectionOptions *)options {
UISceneConfiguration *config = [[UISceneConfiguration alloc] initWithName:@"Main" sessionRole:UIWindowSceneSessionRoleApplication];
config.sceneClass = [UIWindowScene class];
config.delegateClass = [SceneDelegate class];
return config;
}
...在 Info.plist 中只留下这个:
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
</dict>
<key>UIApplicationSceneManifest-macos</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
</dict>
现在它按预期工作。
在 Info.plist 中定义场景配置是否应该完全绕过AppDelegate
?根据文档,似乎应该绕过application:configurationForConnectingSceneSession:options:
,但我没有看到任何迹象表明它也应该绕过application:didFinishLaunchingWithOptions:
。一些教程明确表示该方法仍应运行。
我尝试删除该application:configurationForConnectingSceneSession:options:
方法,以防在两个地方定义配置会混淆 SDK,但application:didFinishLaunchingWithOptions:
仍然没有被调用,只要UISceneConfigurations
在 Info.plist 中。
我可以application:didFinishLaunchingWithOptions:
通过在第一行添加断点来判断是否被调用。除非我将UISceneConfigurations
字典添加到 Info.plist 中,否则断点会被命中,但仅进行该更改会导致断点不会被命中。