`~/Library/Application Scripts/` is a sandbox-friendly location where your users' own scripts should be stored (see `NSApplicationScriptsDirectory`). Your app can then execute (but not modify) those scripts using `NSUserAppleScriptTask`. For instance, your app might provide a simple "Scripts" menu that lists the available user scripts, or it might provide the ability to trigger user-supplied scripts when a certain event occurs (e.g. Mail rules).

`NSUserScriptTask` classes are limited in capability and a chore to use, but execute user scripts outside of the app's own sandbox so the user's ability to control other apps isn't limited by your app's own entitlements. Excellent guide here:

objc.io/issues/14-mac/sandbox-scripting/

The AppleScript-ObjC approach can be used to run your application's internal helper scripts, embedded in the `.app` bundle when Xcode builds the app. ASOC scripts execute in-process and their capabilities are restricted according to your app's sandbox entitlements. For instance, your app might rely on an AppleScript helper script to create a new email message in Apple Mail with To, Subject, and Content fields automatically populated when the user selects "Help ➞ Contact Us".

Official AppleScript-ObjC documentation is thin and only covers calling Cocoa APIs from AppleScript. However, that example project should cover the bits you need to call into AppleScript from another language. If you've ever used other ObjC bridges such as PyObjC or RubyCocoa, you should find it quite familiar. If you need any help with ASOC or AppleScript in general, try the AppleScript mailing list or ask Shane Stanley who's written e-books on ASOC.

But in a project from scratch in a new XCode project, what do I need to do except to include the iTunesBridge.swift, iTunesBridge.applescript and Swift_AppleScriptObjC.entitlements ? No config to do in a plist ?

Correct. Your protocol's return type was all wrong. A more precise type would be `NSArray<NSDictionary<NSString,AnyObject>>`, which I imagine can be written more cleanly as `[[String:AnyObject]]`. (The semantics are subtly different, mind: the first uses ObjC/Cocoa types; the second native Swift ones. Ah, the joys of crossing bridges.)

"But in a project from scratch in a new XCode project, what do I need to do"

- calls `Bundle.main.loadAppleScriptObjectiveCScripts()` during initialization (see AppDelegate.swift) to load those files' script objects into the ObjC runtime as Cocoa-based classes. How and when you instantiate them is up to you.

Ok so everything works fine as expected. I can load all my iTunes playlists from an AppleScript and show them in a tree (NSOutlineView) in a Mac OSX app.

But but as you can see in this short demo, it could takes a long time to load all the data if like me you have more than 500 playlists (iTunes user for 15 years ).

In the AppleScript script, I use the progress methods to show what's happening when the script is executed in Script Editor but in OSX, how can I trigger an event from AppleScript to dispatch the loading progress ?

More Like This

Retrieving data ...

This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the Apple Developer Forums Participation Agreement.