Macos 当使用NSWorkspace在应用程序之间打开URL时,如何发送和接收NSAppleEventDescriptor?
NSWorkspace打开了方法Macos 当使用NSWorkspace在应用程序之间打开URL时,如何发送和接收NSAppleEventDescriptor?,macos,appkit,nsworkspace,appleevents,nsapplication-delegate,Macos,Appkit,Nsworkspace,Appleevents,Nsapplication Delegate,NSWorkspace打开了方法(\u1:withAppBundleIdentifier:[…]): 从URL数组中打开一个或多个文件 要打开的应用程序的NSApplicationLegate具有相应的方法,这些方法将被调用以打开您提供的URL: func application(_ sender: NSApplication, openFile filename: String) -> Bool func application(_ sender: NSApplication, ope
(\u1:withAppBundleIdentifier:[…])
:
从URL数组中打开一个或多个文件
要打开的应用程序的NSApplicationLegate具有相应的方法,这些方法将被调用以打开您提供的URL:
func application(_ sender: NSApplication, openFile filename: String) -> Bool
func application(_ sender: NSApplication, openFiles filenames: [String])
返回到
open(:withAppBundleIdentifier:[…])
,该方法有一个NSAppleEventDescriptor参数:
附加事件参数描述符:NSAppleEventDescriptor?
在AppleEvent样式描述符中指定的其他选项。例如,您可以使用此参数指定启动应用程序时要打开的其他文档
我想向将打开文件的应用程序发送其他信息。 这将类似于通知中的
userInfo
字典
我构造了一个NSAppleEventDescriptor
对象来表示此信息。我可以在NSWorkspaceopen(…)
函数中设置此事件描述符
但我如何在目标应用程序的应用程序委托中接收该事件描述符
应用程序(uquo;openFile:)
函数没有用于事件描述符或任何其他“userInfo
”类型附加信息的参数
代码 根据答案和其他问题,我确定了以下解决方案。我现在得到一个苹果事件的触发处理程序。但是我在NSWorkspace函数上设置的Apple事件不是处理程序中接收到的事件!如何取而代之的是我的苹果活动
发送 已发送Apple事件:
接收 收到苹果事件:
Kaeopendoments事件方法
-[NSWorkspace openURLs:…]
生成一个kAEOpenDocuments
事件,其中包含URL作为沙盒保存书签数据。(请参见+[NSURL URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:
)
additionalEventParamDescriptor:
使用自定义参数创建带有kAEOpenDocuments
的additionalEventParamDescriptor时,此事件似乎与来自-[NSWorkspace OpenURL:…]的底层kAEOpenDocuments事件合并
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];
lldb输出示例:
NSAppleEventDescriptor:'aevt'\'odoc'{~'prdt':'aevt'\'odoc'{
“urln”:“utxt”(“你长得真漂亮””),——:[
“bmrk”(1432/$626F6F6B980…)
注意:为KaePopendCuments设置NSAppleEventManager时,这将覆盖应用程序:openFile:
或应用程序:openFiles:
方法的AppKits内置功能。自定义事件处理程序需要实现所有这些功能
自定义事件方法
根据我的发现,发送带有自定义事件ID的自定义事件类不会触发事件处理程序。'_(ツ)_/“>>>执行此操作时,服务器会向odoc
事件添加一个附加参数。“您的应用程序将只接收以其为目标的Apple事件,即在其目标地址描述符中指定您的应用程序的事件。”查看控制台日志AppleEvents未能对/Users/user/Desktop的扩展名进行编码,err=Operation not allowed/1
-这是我在Apple脚本中发送的目标之一…不要费心传递额外的EventParamDescriptor。很难正确,而且我已经看到证据表明它甚至没有正确传递。(我已经直接使用Launch Services,它确实正确地传递了参数。)我使用的是eventClass:AEEventClass(kCoreEventClass),eventID:AEEventID(Kaeopendictions)
。我得到了回调,但奇怪的是,它在处理程序中似乎是一个完全不同的事件。我应该使用什么类/ID?或者事件在传输过程中发生更改还有其他原因吗?从我看到的情况来看,您得到的是Kaeopendiuments事件,而不是其他事件。这是有意义的。但我也无法获得自定义事件处理程序我更新了我的答案,从来没有做过你想做的事情。只记得前一段时间玩过一些相关的东西,以为我会尝试一下。问题是,即使我没有在NSWorkspace函数调用中包含additionalEventParamDescriptor:
,我的处理程序也会被触发。在这两种情况下,在在e handler中,事件显示为带有直接对象的“bookmark”事件:希望更新后的答案能够澄清问题……仍然需要解析Kaeopendoments事件。
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)
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)
}
}
- (void)applicationWillFinishLaunching:(NSNotification *)notification {
[[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleAppleEvent:withReplyEvent:) forEventClass:kCoreEventClass andEventID:kAEOpenDocuments];
}
- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
}
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];