将 applicationShouldTerminateAfterLastWindowClosed 与 Mac 催化剂一起使用
Using applicationShouldTerminateAfterLastWindowClosed with Mac Catalyst
我有一个 Mac Catalyst 应用程序,它本质上是一个 window 应用程序,但我添加了多 window 支持(使用场景)以允许打开第二个 window 用于一个功能,一小部分用户将使用该功能。现在 Apple 拒绝了该应用程序,因为有了 multi-window 支持,当用户单击主 window 顶部的红色按钮时,该应用程序不会退出。一种解决方案是提供一个菜单项来重新打开它,但我认为如果应用程序像以前那样简单地退出,对用户来说会更直观。
我发现了一个类似的问题 on the Apple forums and am trying to implement the provided solution. Using this tutorial,它提供了更多设置说明,我添加了一个 macOS 包作为新目标,将其嵌入到 iOS 目标中,并添加了这个 class 到捆绑包:
#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 中,我调用此方法来加载包:
- (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 init
、AppKitBridge window
和 AppKitBridge applicationDidUpdate
行。所以看起来整体设置正在运行。但是当我点击红色的 window 按钮时,它没有显示 AppKitBridge applicationShouldTerminateAfterLastWindowClosed
或 AppKitBridge applicationShouldTerminate
行,应用程序也没有退出。
这应该符合我的预期吗?如果是,我在设置中缺少什么?
问题出在这一行:
NSObject *appKit = [[[bundle classNamed:@"AppKitBridge"] alloc] init];
你的 appKit
对象是一个 局部变量 所以你的 AppKitBridge 实例在一行之后不存在了。如果要将此对象用作 app/window 委托,则需要此对象 persist。将其分配给某个持久对象的实例 属性。
我有一个 Mac Catalyst 应用程序,它本质上是一个 window 应用程序,但我添加了多 window 支持(使用场景)以允许打开第二个 window 用于一个功能,一小部分用户将使用该功能。现在 Apple 拒绝了该应用程序,因为有了 multi-window 支持,当用户单击主 window 顶部的红色按钮时,该应用程序不会退出。一种解决方案是提供一个菜单项来重新打开它,但我认为如果应用程序像以前那样简单地退出,对用户来说会更直观。
我发现了一个类似的问题 on the Apple forums and am trying to implement the provided solution. Using this tutorial,它提供了更多设置说明,我添加了一个 macOS 包作为新目标,将其嵌入到 iOS 目标中,并添加了这个 class 到捆绑包:
#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 中,我调用此方法来加载包:
- (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 init
、AppKitBridge window
和 AppKitBridge applicationDidUpdate
行。所以看起来整体设置正在运行。但是当我点击红色的 window 按钮时,它没有显示 AppKitBridge applicationShouldTerminateAfterLastWindowClosed
或 AppKitBridge applicationShouldTerminate
行,应用程序也没有退出。
这应该符合我的预期吗?如果是,我在设置中缺少什么?
问题出在这一行:
NSObject *appKit = [[[bundle classNamed:@"AppKitBridge"] alloc] init];
你的 appKit
对象是一个 局部变量 所以你的 AppKitBridge 实例在一行之后不存在了。如果要将此对象用作 app/window 委托,则需要此对象 persist。将其分配给某个持久对象的实例 属性。