I would like to pass a float from obj c to applescript or vice versa

If I call this from applescript, I get error. It won’t return anything. I can call ibactions which are basically voids but I can’t figure out how to call a setter or getter in my obj c from my applescript.

#define myVersion 1.25

 vnGet method - disabled for now
    NSString* myVstring = [NSString stringWithFormat:(NSString *) @"%f",myVersion];
    if (beta_version) NSLog(@"myVstring=%@",myVstring);
    return myVstring;

script my_exampleAppDelegate
        property parent : class "NSObject"
	on applicationWillFinishLaunching_(aNotification)
             set my_version_no to my application's vnGet
             display dialog "Congratulations, you are running version" & my_version
	end applicationWillFinishLaunching_
end script

This way I can put my version number in the Obj C header file or in the applescript file but not both. So of course I’d accept it the other way as well. But once again, I can call things from Obj c as long as I don’t try to pass anything but “self” (sender). Of course I’ve tried it with other data types including NSString and Boolean with no luck.

I’ve even thought about writing a floating point number to the info.plist and reading it back in from the other side but that seems stupid.

Am I missing something obvious here or is this really a limitation? All my research so far indicates this is a limitation but I can’t understand why Apple would build a little firewall that allows you to pass events and object pointers back and forth but not values.

Create a “blue box” (object) in the .xib. Then set it to represent your Objective-c file. In the AppleScript, add a property with missing value and in the xib connect it to the blue box. If you name the property otherFile, for example, then this is what you’d do:

set theVersion to otherFile’s vnGet()

You don’t say where you implemented the -vnGet method, but if it’s in a category to the application, you’d call it like this:

set my_version_no to current application's NSApp's vnGet()

Thanks for your help. Unfortunately I’m not able to get this working just yet. My app is an applescript cocoa app in xcode 4. I didn’t create an extra blue box as xcode provided one. Only all the methods look alike. They are


I can define a new one like getvn


and it crashes

even if I do it like


How about going the other way? Can I call an applescript function to return an nsstring to the obj c side?

When I have more time, possibly tomorrow evening, I’ll make a sample app I can paste in its entirety to illustrate the problem.


Well, you forgot the asterisk. That should be

-(nsstring *)getvn

I think that this only works if the Objective-C file is the app delegate, but tell me if I’m wrong. Shane’s solution did not work for me.

set my_version_no to current application's NSApp's getVn()

Sorry. I forgot the * in my post, not my code. The error I get in the console is something vague ( to me) about passing an unexpected value. Even if the code keeps running, the number I try to pass never makes it across.

I still think the best way to do this is through the nib. NSApp is leading me down a dark alleyway with no end :slight_smile:


property myClass : class "MyClass" of current application
    on applicationDidFinishLaunching_(aNotification)
        set theVers to myClass's getVersion()
        log theVers
    end applicationDidFinishLaunching_


The objective-c class MyClass .m file looks like this:

[code]#import “MyClass.h”

@implementation MyClass

  • (id)init
    self = [super init];
    if (self) {


    return self;

-(NSString *)getVersion {

return @"2.5";

The error looks as if its not trying to access getVersion in the right way. It’s a method.

Notice that the error has a + sign: (+[MyClass getVersion]: unrecognized selector sent to class ). The way you are calling the objective-C method is for class methods only not instance methods like getVersion. You should do what you said in your previous post – add the blue cube, and call the method using a property connected to that cube. Or you could just make your getVersion method a class method. You also don’t need the init method, and in your applescript you don’t need “of current application” in your property declaration. If you have your property called otherFile you just need this:

property parent : class "NSObject"
	property otherFile : missing value -- IBOutlet for the MyClass blue cube
	on applicationWillFinishLaunching_(aNotification)
		set theVers to otherFile's getVersion()
		log theVers
	end applicationWillFinishLaunching_

The Objective-C file is just:

@implementation MyClass

-(NSString *)getVersion {
    return @"2.5";


The other way to do it without adding a blue cube in IB, is just to do an alloc init in your code to create an instance of that class, like so:

property parent : class "NSObject"
	on applicationWillFinishLaunching_(aNotification)
		set otherFile to current application's MyClass's alloc()'s init()
		set theVers to otherFile's getVersion()
		log theVers
	end applicationWillFinishLaunching_


Thank you, Ric.

That was included in the default template and since it was a test app I didn’t bother doing anything with it.

I overlooked this; I was lead astray by Shane’s example.

But Info.plist is the designated location to store the version number and retrieve it from there.
Even the AppleScript command version reads the value from Info.plist

Did you put the method in a category on NSApplication? It works fine like that.

But Stefan is correct: Info.plist is the right place for a version number.

Use this to get the version number from the PList:

set dict to current application’s NSBundle’s mainBundle()'s infoDictionary()
set shortVersion to dict’s valueForKey_(“CFBundleShortVersionString”)
ceWindow’s setTitle_("Coupon Exporter " & shortVersion)

NSDictionary *dict = [[NSBundle mainBundle] infoDictionary];
NSString *bundleVersion = [dict valueForKey:@“CFBundleVersion”];
NSString *shortVersion = [dict valueForKey:@“CFBundleShortVersionString”];

I’ll also add that the version number is NOT a real float. Look at Mac OSX: 10.6.8 -that’s not a number, it’s more like a special string. I’m using Sparkle for some of my apps, and it reads the version number from the Plist. If you say “1.25” as a version, then that is a higher number than “1.3”. I was using this sort of decimal notation but then ran into a problem where I couldn’t continue to use Sparkle properly because v2.20 was higher than v2.3… I had to use 2.30. The convention is x.x.x and like the cocoa method shows, it’s a string not a real number.

You can use the above code wherever you need and don’t even have to worry about passing things back and forth across objects.

Thanks for all this great help, guys!

I will give a couple of things a try tonight.

First of all, I’ll move my version to the plist file. I’ve been using a math based method to compare versions so I’ll have to either use 1.20 instead of 1.2 or switch to 1.2.0.

Second of all, I’ll try passing an NSString from Applescript to xcode. This time the method will have a void return but will take an NSString from Applescript. I’ll try adding it to an existing class and see if I can make it work as shown here. If not, I’ll try adding another blue block just to check that option as well.


as the key CFBundleShortVersionString implies, the version information in Info.plist is indeed a string.
Cocoa provides a method to do a numeric comparison for strings

set dict to current application's NSBundle's mainBundle()'s infoDictionary()
set shortVersion to dict's valueForKey_("CFBundleShortVersionString")
set compareVersion to "1.10.2"
set comparisonResult to shortVersion's compare_options_(compareVersion, 64) as integer -- 64 = NSNumericSearch

if comparisonResult is 1 then
	log ((shortVersion as text) & " is higher than " & compareVersion as text)
else if comparisonResult is 0 then
	log ((shortVersion as text) & " is equal to " & compareVersion as text)
else if comparisonResult is -1 then
	log ((shortVersion as text) & " is lower than " & compareVersion as text)
end if

How would you do such a comparison in obj c? What I’m doing ( and getting away with for the moment) is this…

        if( text )
            double newVN = [text doubleValue];
            if ([myVersion doubleValue] >=newVN) {
                update_avail = NO;
                if (beta_version) NSLog(@"No update_avail, Text=%@", text);
            else {
                update_avail = YES;
                if (beta_version) NSLog(@"YES update_avail, Text=%@", text);

I don’t quite know what cocoa makes of “doublevalue” of something like so I’d love to see the equivalent string comparison as integer methods you showed earlier for applescript for obj c.

Edit: Ok, an NSLog reveals cocoa thinks 1.1.7 is 1.10000. Not gonna quite work so yeah I need the cocoa equivalent of set comparisonResult to shortVersion’s compare_options_(compareVersion, 64) as integer.

On the original topic, sadly I cannot pass anything across the impenetrable applescript/obj c barrier yet. I tried a few things but they resulted in errors similar to the unrecognized selector mentioned earlier in this thread.

At this point, now that I’ve got version working to my satisfaction (other than the compare thing in objc), I’m wondering how to pass an NSString from applescript to obj c. That’s the last piece of the puzzle I need for the project I’m working on tonight.

Thanks in advance!

That suggests you’re trying to call an instance method on the class. You need an object, either by instantiating in IB or using alloc()'s init().

Ok here we go. I want to pass an nsstring over to objc from applescript and different nsstring back again.

I whipped up. No I got whipped up on by a test app… Oops. I see one mistake already. I shouldn’t have said tell foo. I should have said tell theclass. Be right back… Ok done. Same result. Fixed “foo” typo and still get ugly dump. I’m sure I’m missing something obvious but I can’t see the forest for the trees.


#import <Foundation/Foundation.h>

@interface foo : NSObject



#import "foo.h"

@implementation foo



    NSString* fee = [NSString stringWithFormat:@"testme"];
    return fee;



script AppDelegate
	property parent : class "NSObject"
	on applicationWillFinishLaunching_(aNotification)
        set theclass to current application's foo's alloc()
        set teststring to theclass's itell
        log teststring
        tell theclass to tellme("bogus")
		-- Insert code here to initialize your application before any files are opened 
	end applicationWillFinishLaunching_
	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits 
		return current application's NSTerminateNow
	end applicationShouldTerminate_
end script

Produces the rather prolific console output as follows…

2011-11-02 20:39:44.686 test123[92229:407] [<foo 0x400aea180> valueForUndefinedKey:]: this class is not key value coding-compliant for the key itell.
2011-11-02 20:39:44.693 test123[92229:407] (
	0   CoreFoundation                      0x00007fff987ed286 __exceptionPreprocess + 198
	1   libobjc.A.dylib                     0x00007fff973bbd5e objc_exception_throw + 43
	2   CoreFoundation 

That should be something like:

set theclassObject to current application’s foo’s alloc()'s init()

That should be:

set teststring to theclassObject’s itell_(me)


tell theclassObject to tellme_(“bogus”)

This stuff works fine, but you have to get the syntax right.

I don’t know why you are trying to convert the version “number” to a number. As Stefan showed, NSString has methods for comparing strings that work fine for this kind of string. Here is objective-C code that a does the same thing as Stefan’s code. Note that to pass a string from ASOC to objective-C, you just have a string as the argument to the method you are calling (compareVersions: in this case). It doesn’t have to be an NSString, an applescript string will do just fine.

script VersionTestAppDelegate
	property parent : class "NSObject"
	on applicationWillFinishLaunching_(aNotification)
		set compareVersion to "1.2.5"
		set otherFile to current application's MyClass's alloc()'s init()
		otherFile's compareVersions_(compareVersion)
	end applicationWillFinishLaunching_
end script

The objective-C file is:

@implementation MyClass

-(void) compareVersions:(NSString *)compareVersion {
    NSDictionary *dict = [[NSBundle mainBundle] infoDictionary];
    NSString *shortVersion = [dict valueForKey:@"CFBundleShortVersionString"];
    NSComparisonResult comparisonResult = [shortVersion compare:compareVersion];
    switch (comparisonResult) {
        case 1:
            NSLog(@"%@ is higher than %@",shortVersion,compareVersion);
        case 0:
            NSLog(@"%@ is equal to %@",shortVersion,compareVersion);
        case -1:
            NSLog(@"%@ is lower than %@",shortVersion,compareVersion);


Notice that I use just use the simple compare: method rather than compare:options: method that Stefan used – I found that this works better. Using the NSNumericSearch option gives 1.25 as higher than 1.3 whereas the simple compare: method gets this case right (both work fine if you stick to the x.x.x type of format with only one digit between each dot).


Worked! Thanks! Oh, that last tell me_(“bogus”) was tellme_(“bogus”)…

Now I’m off to try to integrate this in my code…