2

我有一个旧的(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 中,否则断点会被命中,但仅进行该更改会导致断点不会被命中。

4

0 回答 0