Question

I would like to launch applications (or send to them using AppleEvents) using NSPasteboard data just like is done in the Finder when you drag and drop a file, text, image on an application (or in the Dock) and it launches or invokes the data in the app.

Launch services functions like LSOpenFromURLSpec work only for files and I see there is an option to arbitrary parameters of AppleEvents but I could not figure out how to make this work.

Another question would be is the sandboxable but I'm not sure it's possible at all yet.

Thank you.

Was it helpful?

Solution

When you're the receiver, what happens depends on what the user is dropping:

  • One or more files

    The application is sent one or more open document Apple Events. NSApplication tries to send at least one (should really be only one, but this has been broken for a few versions) message to its app delegate before trying the document controller.

  • One or more URLs (not of the file: scheme)

    The application is sent one or more get-URL events. You'd need to implement an Apple Event handler for this. Conveniently, this is the example the Apple Event handling documentation uses.

  • Any other data

    You need to implement a service. Which service will be used for Dock drops is auto-detected based on types, and I don't know how it picks among multiple matches; there's no way to specify only certain services as being available to the Dock. You guessed correctly with regard to NSPasteboard: You implement services using pasteboards for I/O.


When you're the sender:

  • Sending files

    The easiest way is to use Launch Services. This will send the appropriate Apple Events on your behalf.

  • Sending URLs

    Again, Launch Services will send the requisite Apple Events for you. Indeed, in modern code, you'll probably use the same LSOpen API(s) for both file and non-file URLs.

  • Sending any other data

    As the receiving application must implement a service, so must you perform a service.

    The hard part is discovery: you need to know which service you want to perform, and it needs to be available. I assume that you know which application you'll be sending to (simulating a drop onto), which is a leg up on most people who'll intend to send to a service. I'm pretty sure you'll just have to look at the target application's Info.plist and find which service best matches the types you have yourself.

    One potential wrinkle is that you can't specify an application bundle. You'll have to hope that the targeted application's services are enabled to show up in the Services menu, and you'll have to figure out the correct menu item name yourself. (Experiment with what's showing up in your own Services menu to try to derive the correspondence.) Even if you come up with the correct service item name and the service is enabled, there's no guarantee that the service will be performed by the application in the bundle you were looking at—it may be a different version or even (possibly, depending on how the names are constructed) a different app that has a service with the same name.

    You may want to file a Radar about this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top