首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用NSAppleEventDescriptor打开应用程序之间的URL时,如何发送和接收NSWorkspace?

在使用NSAppleEventDescriptor打开应用程序之间的URL时,如何发送和接收NSWorkspace?
EN

Stack Overflow用户
提问于 2019-08-09 23:29:33
回答 1查看 1.3K关注 0票数 2

NSWorkspace有open(_:withAppBundleIdentifier: [...] )方法

从URL数组打开一个或多个文件。

代码语言:javascript
复制
func open(_ urls: [URL], 
     withAppBundleIdentifier bundleIdentifier: String?, 
     options: NSWorkspace.LaunchOptions = [], 
     additionalEventParamDescriptor descriptor: NSAppleEventDescriptor?, 
     launchIdentifiers identifiers:) -> Bool

要打开的应用程序的NSApplicationDelegate具有相应的方法,这些方法被调用来打开您提供的URL:

代码语言:javascript
复制
func application(_ sender: NSApplication, openFile filename: String) -> Bool
func application(_ sender: NSApplication, openFiles filenames: [String])

回到open(_:withAppBundleIdentifier: [...]),该方法有一个NSAppleEventDescriptor参数:

additionalEventParamDescriptor descriptor: NSAppleEventDescriptor? 在AppleEvent样式描述符中指定的其他选项。例如,您可以使用此参数指定在启动应用程序时打开的其他文档。

我想发送更多的信息到应用程序,将打开文件。

这将类似于通知上的userInfo字典。

我构造了一个NSAppleEventDescriptor对象来表示这些信息。我可以在NSWorkspace open( ... )函数中设置这个事件描述符。

但是,如何在目标应用程序的应用程序代理中接收这个事件描述符呢?

application(_: openFile:)函数没有事件描述符的参数或任何其他"userInfo"-type附加信息。

代码

根据答案和其他问题,我确定了下面的解决方案。我现在得到了一个苹果事件的触发处理程序。但是我在NSWorkspace函数上设置的Apple不是在处理程序中接收的事件!我如何让代替我的苹果事件呢?

发送

代码语言:javascript
复制
let appleEvent = NSAppleEventDescriptor(eventClass:       AEEventClass(kCoreEventClass),
                                        eventID:          AEEventID(kAEOpenDocuments),
                                        targetDescriptor: nil,
                                        returnID:         AEReturnID(kAutoGenerateReturnID),
                                        transactionID:    AETransactionID(kAnyTransactionID))
appleEvent.setDescriptor(NSAppleEventDescriptor(string: "THIS IS A TEST"), forKeyword: keyDirectObject)

let didOpen = AppKit.NSWorkspace.shared.open([URL(fileURLWithPath: "/path/image.png")],
                                             withAppBundleIdentifier: bundleID,
                                             options: [.withErrorPresentation],
                                             additionalEventParamDescriptor: appleEvent,
                                             launchIdentifiers: nil)

发送苹果事件:

<NSAppleEventDescriptor: 'aevt'\'odoc'{ '----':'utxt'("THIS IS A TEST") }>

接收

代码语言:javascript
复制
class AppDelegate: NSObject, NSApplicationDelegate {
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        NSAppleEventManager.shared().setEventHandler(self,
                                                     andSelector: #selector(handle(event:replyEvent:)),
                                                     forEventClass: AEEventClass(kCoreEventClass),
                                                     andEventID: AEEventID(kAEOpenDocuments))
    }
    
    @objc func handle(event: NSAppleEventDescriptor?, replyEvent: NSAppleEventDescriptor?) {
        guard let event = event,
            event.eventClass == AEEventClass(kCoreEventClass) && event.eventID == AEEventID(kAEOpenDocuments) else {
            return
        }

        guard let additionalEventParamDescriptor = event.paramDescriptor(forKeyword: keyAEPropData) else {
            return
        }

        
        guard let directObject = additionalEventParamDescriptor.paramDescriptor(forKeyword: keyDirectObject) else {
            return
        }
        
        print(directObject)
    }
    
}

收到苹果事件:

<NSAppleEventDescriptor: 'aevt'\'odoc'{ '----':[ 'bmrk'(888/$626F6F6B7803000000000 [....] 00000AC01000000000000...$) ] }>

EN

回答 1

Stack Overflow用户

发布于 2019-08-12 09:39:09

kAEOpenDocuments事件法

代码语言:javascript
复制
- (void)applicationWillFinishLaunching:(NSNotification *)notification {
    [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleAppleEvent:withReplyEvent:) forEventClass:kCoreEventClass andEventID:kAEOpenDocuments];
}

- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {

}

-[NSWorkspace openURLs: ...]生成一个kAEOpenDocuments事件,其中包含URL作为沙箱保存书签数据。(见+[NSURL URLByResolvingBookmarkData: options: relativeToURL: bookmarkDataIsStale: error:])。

The additionalEventParamDescriptor

当使用自定义参数创建带有additionalEventParamDescriptor的kAEOpenDocuments时,该事件似乎与-[NSWorkspace openURLs: ...]中的底层kAEOpenDocuments事件合并。

代码语言:javascript
复制
NSAppleEventDescriptor *targetDescriptor = nil;
NSAppleEventDescriptor *appleEvent = nil;

targetDescriptor = [NSAppleEventDescriptor descriptorWithDescriptorType:typeApplicationBundleID
                                                                   data:targetBundleID];
appleEvent = [NSAppleEventDescriptor appleEventWithEventClass:kCoreEventClass
                                                      eventID:kAEOpenDocuments
                                             targetDescriptor:targetDescriptor
                                                     returnID:kAutoGenerateReturnID
                                                transactionID:kAnyTransactionID];
[appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithString:@"You're so good looking"]
                    forKeyword:'urln'];

[[NSWorkspace sharedWorkspace] openURLs:@[ [[NSBundle mainBundle] resourceURL] ]
                withAppBundleIdentifier:bundleIdentifier
                                options:NSWorkspaceLaunchNewInstance
         additionalEventParamDescriptor:appleEvent
                      launchIdentifiers:NULL];

样本十一分贝输出:

NSAppleEventDescriptor:'aevt'\'odoc'{ ~‘prdt’:‘aevt’\\‘odoc’{‘urln’:‘utxt’(“You‘t’‘re”) },’--‘-’'bmrk'(1432/$626F6F6B980 .)}

注意:当为kAEOpenDocuments设置NSAppleEventManager时,这会覆盖application:openFile:application:openFiles:方法的AppKits内置功能。自定义事件处理程序需要实现所有这些。

自定义事件方法

根据我的发现,发送带有自定义事件ID的自定义事件类,不触发事件处理程序,而不是。¯_(ツ)_/

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57438168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档