2 Replies
      Latest reply on Aug 21, 2019 11:22 AM by pkamb
      pkamb Level 1 Level 1 (0 points)

        NSWorkspace has the method `open(_:withAppBundleIdentifier: [...] )`:

         

         

        > Opens one or more files from an array of URLs.

         

         

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

         

        ---

         

         

        The NSApplicationDelegate *of the app you want to open* has corresponding methods that are called to open the URL(s) you provide:

         

         

            func application(_ sender: NSApplication, openFile filename: String) -> Bool
            func application(_ sender: NSApplication, openFiles filenames: [String])

         

        ---

         

         

        Back to `open(_:withAppBundleIdentifier: [...])`, that method has an NSAppleEventDescriptor parameter:

         

         

        > **`additionalEventParamDescriptor descriptor: NSAppleEventDescriptor?`**

        > Additional options specified in an AppleEvent-style descriptor. For example, you could use this parameter to specify additional documents to open when the app is launched.

         

         

        ---

         

         

        ###I would like to send additional information to the app that will open the files.

         

         

        This would be used similarly to the `userInfo` dictionary on a notification.

         

         

        I've constructed a `NSAppleEventDescriptor` object to represent this information. I can set this event descriptor in the NSWorkspace `open( ... )` function.

         

         

        But how do I **receive** this event descriptor in Application Delegate of the target app?

         

         

        The `application(_: openFile:)` functions have no parameters for the event descriptors or any other "`userInfo`"-type additional information.

         

         

        ---

         

         

        ## Code

         

         

        Based on answers and other questions, I settled on the solution below. I am now getting a triggered handler for Apple Events. But the Apple Event that I am setting on the NSWorkspace function is not the one that is received in the handler! How do I get **my** Apple Event instead?

         

         

        ---

         

         

        ## Send

         

        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: AEKeyword(keyDirectObject))
        
        
        let didOpen = AppKit.NSWorkspace.shared.open([URL(fileURLWithPath: "/path/image.png")],
                                                     withAppBundleIdentifier: bundleID,
                                                     options: [.withErrorPresentation],
                                                     additionalEventParamDescriptor: appleEvent,
                                                     launchIdentifiers: nil)

        ### Sent Apple Event:

         

         

        > `<nsappleeventdescriptor: 'aevt'\'odoc'{="" '----':'utxt'("this="" is="" a="" test")="" }="">`

         

        ---

         

         

        ## Receive

         

         

        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 directObject = event.paramDescriptor(forKeyword: keyDirectObject) else {
                    return
                }
               
                print(directObject)
            }
           
        }

         

        ### Received Apple Event:

         

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

         

        Can anyone help me understand why the Apple event I send along with NSWorkspace `open()` is not the Apple Event that I receive in my handler?

         

        Sorry for the wall of text above (easier to see in markdown)

         

        Please let me know if there's anything I can add.