【问题标题】:Using applicationShouldTerminateAfterLastWindowClosed with Mac Catalyst在 Mac Catalyst 中使用 applicationShouldTerminateAfterLastWindowClosed
【发布时间】:2020-09-20 19:29:55
【问题描述】:

我有一个 Mac Catalyst 应用程序,它本质上是一个单窗口应用程序,但我添加了多窗口支持(使用场景)以允许为一个功能打开第二个窗口,一小部分用户会使用该功能。现在 Apple 拒绝了该应用程序,因为它支持多窗口,当用户单击主窗口顶部的红色按钮时,该应用程序不会退出。一种解决方案是提供一个菜单项来重新打开它,但我认为如果应用程序像以前那样简单地退出,对用户来说会更直观。

我发现了一个类似的问题on the Apple forums 并正在尝试实施提供的解决方案。使用提供更多设置说明的this tutorial,我添加了一个 macOS 包作为新目标,将其嵌入到 iOS 目标中,并将此类添加到包中:

#import "AppKitBridge.h"

@implementation AppKitBridge

@synthesize application;
@synthesize window;

- (id)init {
    NSLog(@"AppKitBridge init");
    self = [super init];

    self.application = [NSApplication sharedApplication];
    self.window = [[self.application windows] firstObject];
    if (self.window) {
        self.application.delegate = self;
        self.window.delegate = self;
    } else {
        NSLog(@"AppKitBridge error: window is nil");
    }

    return self;
}

- (void)test {
    NSArray *windows = NSApplication.sharedApplication.windows;
    for (NSWindow *window in windows) {
        NSLog(@"AppKitBridge window: %@", window);
    }
}

- (void)applicationDidUpdate:(NSNotification *)notification {
    NSLog(@"AppKitBridge applicationDidUpdate");
}

- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
    NSLog(@"AppKitBridge applicationShouldTerminateAfterLastWindowClosed");
    return TRUE;
}

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
    NSLog(@"AppKitBridge applicationShouldTerminate");
    return TRUE;
}

@end

然后在iOS应用的初始视图控制器的viewDidLoad中,我调用这个方法来加载bundle:

- (void)enableAppKit {
    NSString *pluginPath = [[[NSBundle mainBundle] builtInPlugInsPath] stringByAppendingPathComponent:@"AppKit.bundle"];
    NSBundle *bundle = [NSBundle bundleWithPath:pluginPath];
    [bundle load];
    NSObject *appKit = [[[bundle classNamed:@"AppKitBridge"] alloc] init];
    [appKit performSelector:@selector(test) withObject:nil afterDelay:0];
}

当我运行应用程序时,控制台会显示AppKitBridge initAppKitBridge windowAppKitBridge applicationDidUpdate 行。所以看起来整体设置是有效的。但是当我点击红色窗口按钮时,它没有显示AppKitBridge applicationShouldTerminateAfterLastWindowClosedAppKitBridge applicationShouldTerminate 行,并且应用程序没有退出。

这应该符合我的预期吗?如果是,我在设置中缺少什么?

【问题讨论】:

  • 我试图从几篇展示该技术的一部分或另一部分的文章中将其拼凑起来。我还没有找到完整的解释,而且我以前从未做过像嵌入包这样的事情,所以我很可能遗漏了一些东西。
  • 好的,我明白了。我只是初始化 AppKitBridge 类来测试捆绑包正在加载,并没有意识到主应用程序需要初始化和保留该实例才能使其继续工作。那解决了它!如果您想将此作为答案,我会接受。 (我不需要“Objective-C 的基础知识”,我只是不熟悉这个 AppKit 桥接理念,不知道这些部分可以组合在一起。)

标签: ios objective-c appkit mac-catalyst


【解决方案1】:

问题出在这一行:

NSObject *appKit = [[[bundle classNamed:@"AppKitBridge"] alloc] init];

您的appKit 对象是一个局部变量,因此您的 AppKitBridge 实例会在一行之后消失。如果要作为应用程序/窗口委托,您需要此对象persist。将其分配给某个持久对象的实例属性。

【讨论】:

  • 太棒了!进行此更改后,我可以确认一切正常。
猜你喜欢
  • 2020-02-05
  • 1970-01-01
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-19
  • 2021-02-21
  • 2023-03-22
相关资源
最近更新 更多