I’ve been searching for a post that mentioned adding applescript file to an existing cocoa project without luck.
Is it possible to call an applescript class method from cocoa app? I tried adding the class and connecting it to an instance in IB but can not connect to that instance. I guess the alternative is to build an ASOC app first and add all the oBJ-c files in there but it would be great to do it the other way.
Wow, timing… I was JUST now reading this one where Shane explains it a bit, but I’m still not getting it to work just right. But, it’s at: http://macscripter.net/viewtopic.php?id=31322
Actually, I’m looking to tie it in without IB being involved, making an Obj-C Command-Line tool. Getting errors, but I think I’m missing an alloc/init, since it’s not tied to a “blue box” in IB.
I added a blue cube in IB and set its class to that of my testScript.applescript but it won’t connect to either my oBJ-c delegate or to any button. Not sure what I am doing wrong here…
I found the same thing… I followed that post exactly, with same names and everything. Being still kind of new it took me a while (and many new projects) to figure out what was what. But, I ran into what you did… Finding that things would not allow to hook up like I expected.
My problem, though, is that I haven’t done this much even without ASOC injected, so I can’t tell just at a glance what’s wrong.
Shane is pretty sharp around here, I’ve seen by browsing around, but I have a feeling that he whipped that one up without testing and ended up with just a small error.
Here’s to looking around some more. Google searching for “loadAppleScriptObjectiveCScripts” doesn’t turn up much, but any example code that’s complete will need to include that, I think.
Here’s to pressing on and trying again and again. My error count is dropping, at least.
I’m seeing the same thing. At best, following Shane’s example code, I seem to remember getting a warning at this line:
[myASClass myTest];
… saying that myASclass may not understand the -myTest method. Maybe because there’s no @interface letting other objects know what methods our object understands?
I’m going to hit the beginner docs and start out with plain simple new ObjC objects right from the top and see if I can follow along step by step with how an AS object relates…
Ok. I found the document I was wanting. From Apple, a well written “Introduction to the Objective-C Programming Language” guide.
Which at first makes me think that we need an @interface to let other objects know what methods it understands, but then I see that we name our superclass with:
// Obj-C:
@interface myObjcClass : NSObject {
}
@end
// ASOC
script myASclass
property parent : class "NSObject"
end script
So is this handling our @interface? I can see how an ASOC object can run a method (or handler) in our scripts without an @interface, but I’m wondering if the ASOC framework is enough to let Obj-C class know what methods our object provides without an @interface?
As far as I can see, you can’t call an AS handler as a class method from Objective-C. The problem happens at compile time, presumably because the compiler can’t handle AS classes – the fact that instance methods work is probably because a variable is used and the class is recognised at runtime.
(That’s it’s not a problem with class methods per se is shown by using something like “[[myASClass class] myTest]” where myASClass is an IBOutlet connected to an AS class. I guess there may be some way of referring to a class dynamically that I don’t know of.)
However, you can call AS handlers as instance methods provided you instantiate in the nib (obviously you can’t instantiate in code because that means using class methods like alloc and init). The code pointed to does that, and I just tested it here again – it does work, nothing left out.
Even with instance methods, you’ll get compiler warnings because there’s no AS equivalent of .h files. You can ignore them, but if they annoy you, you can get rid of them by defining them in a formal protocol and having one of your Objective-C classes say it implements it.
Got it! Don’t know why it didn’t work the first few times around. does now.
Yes Garbage collection was off. I am learning obj-c and memory management, finally gaining a foothold there. I suppose it is mandatory to turn GC on if using ASOC applescript classes?
That’s what I thought, but just including the script without calling any methods seems to trigger the warning. I commented out the code and still get “autoreleased with no pool in place - just leaking.” What is getting autoreleased?
script ASClass
property parent : class "NSObject"
(*on callDialog_(sender)
display dialog "Hello world"
end callDialog_
on displayDialog()
display dialog "Hello world"
end displayDialog*)
end script
Is your test using both an ObjCClass.h and ObjCClass.m ??? That’s what I had set up:
Well, I got mine to work finally, but I had to make a change to…
Which I thought looked funny at first, and seemed to react the wrong way (from what I expected) in IB.
From a bit of experience in pure ASOC, this is telling me that any messages I want to send to an instance of ASClass are actually going to be sent to SomeAppAppDelegate, since “myASClass” is tied to it with “IBOutlet SomeAppAppDelegate *myASClass;”. Thus the error messages I was getting:
I looked your code over and over and over and thought it seemed wrong, but you had indicated that it works, so I figured I was just not understanding some message passing voodoo when working in real ObjC.
So when I see:
This tells me that I’m wanting to invoke the “myTest” method on SomeAppAppDelegate. That seems to match error in the log. So I changed the IBOutlet and fixed broken connections in IB:
Now I’m getting my messages (method calls) properly in ASClass. Whew. As I expand on that and run more tests I find something interesting. I get warning messages on 3 of these 4 methods:
I understand you said we can ignore them, but I find it interesting that it thinks one with an arg is valid, but not one without. Haven’t tested multiple args yet.
Another thing to note: You can set up an “on init()” method in your ASClass to set some values on instance variables, as opposed to just setting their value in the class script (like property testProperty : “Default value of testProperty”).
You just have to make sure to end it with “return me”. Otherwise you won’t get an instance of your object when the app starts.
property instanceVar : ""
property instanceUser : ""
on init()
set my instanceVar to "Value of instanceVar set in init()"
set my instanceUser to (short user name of (system info))
return me
end init