如果启动应用程序打开特定文档,如何防止自动状态恢复?

问题描述 投票:0回答:1

我已经在我的 AppKit (Cocoa) 应用程序中实现了状态恢复。这有效。

但是:如果用户通过双击应用程序保存的文档文件来打开应用程序,那么我希望应用程序不要恢复以前的窗口,而是打开在Finder中打开的文档。

问题是状态恢复似乎发生在调用打开文档文件的处理程序之前,因此即使我有办法抑制状态恢复,我也不知道此时待处理的 openURL 调用.

我知道我可以检查启动参数,但这似乎是一种相当肮脏的方式。我认为我应该能够以某种方式从应用程序对象查询存储的文件路径/URL,但我找不到任何东西。

或者我可以更改恢复文档与打开文档的顺序吗?到目前为止,我发现这两种情况都发生在

[NSDocument restoreDocumentWindowWithIdentifier:state:completionHandler:]

 深处,在completionHandler 函数内部。不过,我找不到低于该功能的可重写函数,我可以对此进行更多控制。

我通过在我的 NSDocument 子类中实现

restoreStateWithCoder:

encodeRestorableStateWithCoder:
 来执行状态恢复。

swift objective-c macos cocoa state-restoration
1个回答
1
投票
我当前的解决方案是拦截

odoc

 AppleEvent,如果调用了该事件,则设置一个标志,使 
[NSApp restoreWindowWithIdentifier:]
 返回 NO。

这是里面的代码

AppDelegate.m

static AEEventHandlerUPP openDocHandler = NULL; static SRefCon openDocRefcon; static pascal short HandleOpenDocMessage (const AEDesc *theAppleEvent, AEDesc *reply, void* handlerRefcon) { // intercepts the "odoc" Event to check if we're about to open any files, and then continues with the original handler NSAppleEventDescriptor *event = [NSAppleEventDescriptor.alloc initWithAEDescNoCopy:theAppleEvent]; NSURL *url = [NSURL URLWithString:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]]; if (url) { NSString *docType = [NSDocumentController.sharedDocumentController typeForContentsOfURL:url error:nil]; if ([docType isEqualToString:@"..."]) { // I can check for particular types here in case I can open several [(Application*)NSApplication.sharedApplication setSuppressRestorationOfSearchWindows:YES]; } } return openDocHandler (theAppleEvent, reply, openDocRefcon); } - (void)applicationWillFinishLaunching:(NSNotification *)notification { AEGetEventHandler(kCoreEventClass, kAEOpen, &openDocHandler, &openDocRefcon, false); AEInstallEventHandler(kCoreEventClass, kAEOpen, HandleOpenDocMessage, (__bridge SRefCon)(self), false); ...
内部

Application.h

@property (assign) BOOL suppressRestorationOfSearchWindows;
内部

Application.m

- (BOOL)restoreWindowWithIdentifier:(NSString *)identifier state:(NSCoder *)state completionHandler:(void (^)(NSWindow *, NSError *))completionHandler // override { if ([identifier isEqualToString:@"MyWindowType"] && self.suppressRestorationOfSearchWindows) { // prevent window restoration on startup if the user launched this app by opening a file of my particular type return NO; } else { // continue with regular state restoration return [super restoreWindowWithIdentifier:identifier state:state completionHandler:completionHandler]; } }
不过感觉像是黑客攻击。

© www.soinside.com 2019 - 2024. All rights reserved.