Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run AppleScript from Cocoa Application

Is it possible to run an AppleScript code inside an Cocoa Application?

I've tried NSAppleScript class, but no success.

Also, does Apple allow this?

like image 335
Fábio Perez Avatar asked Feb 05 '11 21:02

Fábio Perez


3 Answers

Solved!

Xcode wasn't saving my script file into app's resources path. To run an AppleScript code from Cocoa Application, use this:

NSString *path = [[NSBundle mainBundle] pathForResource:@"ScriptName" ofType:@"scpt"];
NSURL *url = [NSURL fileURLWithPath:path];NSDictionary *errors = [NSDictionary dictionary];
NSAppleScript *appleScript = [[NSAppleScript alloc] initWithContentsOfURL:url error:&errors];
[appleScript executeAndReturnError:nil];

Swift 5.6.1:

import AppleScriptObjC
import Cocoa

let path = Bundle.main.path(forResource: "ScriptName", ofType: "scpt")
let url = URL(fileURLWithPath: path ?? "")
var errors: [AnyHashable : Any] = [:]
let appleScript = NSAppleScript(contentsOf: url, error: &errors)
appleScript?.executeAndReturnError(nil)
like image 114
Fábio Perez Avatar answered Oct 17 '22 01:10

Fábio Perez


You mentioned xcode wasn't saving the script to your app's resources path. That is correct. You have to tell xcode to do this. First add the compiled script to your project. Then open your target and find the "Copy Bundle Resources" action. Drag your script from the files list into that action. This way your script is copied to your app's resources automatically so you don't have to do it by hand.

Whenever I use a compiled AppleScript in a cocoa application I, 1) add the script to the project, 2) create a new class to control the AppleScript, 3) use the below init method for the class, and 4) drag the script to the "Copy Bundle Resources" action of the target.

- (id)init {
    NSURL *scriptURL = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:@"applescripts" ofType:@"scpt"]];
    if ([self initWithURLToCompiledScript:scriptURL] != nil) { //attempt to load the script file
    }

    return self;
}
like image 20
regulus6633 Avatar answered Oct 16 '22 23:10

regulus6633


From Apple Documentation https://developer.apple.com/library/mac/technotes/tn2084/_index.html

- (IBAction)addLoginItem:(id)sender
{
    NSDictionary *errorDict;
    NSAppleEventDescriptor *returnDescriptor = NULL;

    NSAppleScript *scriptObject = [[NSAppleScript alloc] initWithSource:
                @"\
                set app_path to path to me\n\
                tell application \"System Events\"\n\
                if \"AddLoginItem\" is not in (name of every login item) then\n\
                make login item at end with properties {hidden:false, path:app_path}\n\
                end if\n\
                end tell"];

    returnDescriptor = [scriptObject executeAndReturnError: &errorDict];

    if (returnDescriptor != NULL)
    {
        // successful execution
        if (kAENullEvent != [returnDescriptor descriptorType])
        {
            // script returned an AppleScript result
            if (cAEList == [returnDescriptor descriptorType])
            {
                 // result is a list of other descriptors
            }
            else
            {
                // coerce the result to the appropriate ObjC type
            }
        } 
    }
    else
    {
        // no script result, handle error here
    }
}
like image 41
Huynh Inc Avatar answered Oct 16 '22 23:10

Huynh Inc