Executing AppleScript from Objective-C

Last few days i’ve been busy with extending What’s Tuned with user defined Apple Script. With functions written in Apple Script (called Inserts in What’s Tuned), the user can enrich and customise the content displayed in What’s Tuned. 

See the Apple Script snippet below where 1 argument passed to the function GETARTISTINFO and a list is returned containing (a.o.) a HTML string. In this function info is gathered from YouTube and Wikipedia and formatted into an HTML text. This HTML text is then shown as a NSAttributedString in a normal NSTextField.

Fig1: Apple Script for getting information on artist from Wikipedia & Spotify (this code is available on Github)

The above Apple Script will output the following result in What’s Tuned Artist Bio pane:  

This is how it looks like in What’s Tuned Artist Bio pane

Blocking or Async?

So far I did not see any problems executing different functions in the same script in parallel (async) . Simply dispatch the executeFunction:: to the global run queue and dispatch the processing of the resulst to the main queue.

-(void) executeFunctionASync: (NSString* _Nonnull) functionName 
               withArguments: (NSArray* _Nullable) scriptArgumentArray 
                    andBlock: (
processResultsBlock _Nonnull ) processResultsBlock {
   dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^(void) {
      
// Run in background (global queue)
      NSAppleEventDescriptor* resultDesc = [self executeFunction: functionName withArguments: scriptArgumentArray];
         // Run in background (main queue) save for GUI updates
         dispatch_async( dispatch_get_main_queue(), ^(void) {
            processResultsBlock( resultDesc ); 
         });

      });
}

Apple Script from a sandboxed app

Of course there are restrictions to the execution of the apple script when running from a sandboxed app. One can only make use of applications that have been granted access in the entitlements file of you app. However, do shell command works perfect using shell commands like cURL. Parsing of simple XML data can be easily done by standard Apple Script through:

on extractBetween(someText, startText, endText)
    set
startOffset to offset of startText in someText
    set endOffset to offset of endText in someText
    set startOffset to startOffset + (length of startText)
    set
endOffset to endOffset - 1
    set
finaltext to text startOffset thru endOffset of someText
    return finaltext
end extractBetween

on run
    
set extractedText to extractBetween(“My text to be <title>searched</title> and extracted.", "<title>", "</title>")
end run

Github

You can find the easy to use Objective-C class for executing Apple Script on Github in case you would want to add such support to your own application.

A repository for Apple Script examples can be found here. Please feel free to add your creative Apple Script snippets too so that others can benefit from it as well.

© Plauw 2014-2019 - Cookie free website