Run Script from Xcode Project Resources Folder

In AppleScript, I know how to run another AppleScript.

run script "Path:To:Script.scpt" as alias

In AppleScriptObjC I know how to do that but I’m not sure how to run a script from my Xcode project “Resources” folder.

Thanks in advance, Seb.

Model: MacBook Pro 15"
AppleScript: 2.1.1
Browser: Google Chrome 5.0.375.38
Operating System: Mac OS X (10.6)

You can still use run script. To get the path, you can use NSBundle, something like:

set posixPath to current application’s NSBundle’s pathForResource_ofType_(“Script name”,“scpt”)

This needs one adjustment, because pathForResource_ofType_ is an instance method, so you need to get the mainBundle first:
set posixPath to current application’s NSBundle’s mainBundle’s pathForResource_ofType_(“Script name”,“scpt”). But I found other problems here – I couldn’t get it to work with a .scpt file. I’ve used this method in another program where I was getting the path to a .tiff file, and that worked fine. If I log posixPath here, I keep getting “null”, and I tried 3 different script files just to be sure. If I saved my script as an application, then this code sort of worked:

set posixPath to NSBundle's mainBundle's pathForResource_ofType_("Beeper", "app") as string
		run application posixPath

I get a path ok, but the app, which is supposed to beep three times, just beeped twice and then gave me an error:
Beeper got an error: Connection is invalid. (error -609). So I’m not sure what is going on. You should try it with a .scpt file in your program and see if it works for you (as a .scpt file, my Beeper script worked if I hard coded in the path).

Yes, I forgot about mainBundle. Have a look inside your Resources folder – it looks to me that when you add a .scpt file to Resources in Xcode, it doesn’t get added to the final build. I had to go to Targets and add it to Copy Bundle Resource manually.

I also wonder whether it might be a good idea to add it to a subfolder, to stop it being loaded at startup. Of course being in a subfolder might not make any difference.

After finally managing to get my scripts into the Copy Bundle Resources thing, neither of those bits of code work :frowning:

Works for me:

		set posixPath to current application's NSBundle's mainBundle's pathForResource_ofType_("Sample", "scpt") as string
		set scriptAlias to (posixPath as text) as POSIX file
		run script scriptAlias

Why do you want to do this?

Any applescript you want to run could just be included in the application as either its own ASOC class or as a handler/method in an existing class.

Ease of porting something that’s already working?

I’ve made this in AppleScript, but I’m porting it to AppleScriptObjC so I can work on the interface more and do more advanced things. I’ve got 27 applescripts, some of which are quite long, which I put in a folder and the original applescript that I’m porting just launched them and had their paths written. I might want to distribute this application, just to a few close friends…

I just tried that again and it works! Thanks very much for that :slight_smile:

How could I include an applescript as its own ASOC class?

It’s pretty straightforward. In XCode, Make a new file … class… ASOC.

And you can basically paste in your applescript into the middle of the file that is created. Make sure that you change the names of any handlers you want to call from outside the class into ASOC methods by adding an underscore between name and parentheses; i.e. from doThething() to doTheThing_()

A typical applescript handler:

as its own ASOC class:

Then, to call the methods in your new ASOC class from another ASOC class, the easiest thing to do is add your new class to your application’s Interface Builder NIB and connect it to a property in the ASOC class you want to call your methods from.

Would I use the same kind of code to import an Obj C .m class?

Yeah. Just bring in the Obj C class “blue cube” into your Interface Builder NIB, and link it to a property (with missing value) in the ASOC class you want to call that Obj C class from.

If you have an Obj C class with a method [doTheThing:]