Translate ASOC into Objective-C?

Hello,

For some time now, I’m using ASOC and I really like it – but I’ve got the feeling that the main challenge is not to learn the Applescript bridge itself, but how to use the cocoa framework: to find the most suitable method, its arguments and return value, and so on.

And coerce, coerce, coerce. Sometime uselessly, but “it doesn’t hurt”.

So I was wondering, as my application does not communicate with others, as the only AS part is to «set myList to files of folder XYZ» (that the File Manager does, and much more quickly), I was wondering if I could use Objective-C instead.

The reasons are:

a) use Xcode at its full capacity (type checking, compiling, debugging)
b) avoid coercion paranoia
c) get full access to cocoa (no, no, not Core Foundation as first toy)
e) develop for the iOS platform
f) be assured that my applications won’t become just garbage if Apple abandon ASOC as they did for ASStudio.

There are other signs that push me into this direction: the lack of documentation for ASOC, the fact that the answers from the ASOC MacScripters often come as Objective-C solutions (new classes or new categories), with sentences like “I don’t know if it can be done in ASOC, but I guess so”, “In Objective-C you would just write this”, and so on.

Of course, they are some disadvantages:

a) I don’t like C and its avatars. C may be efficient and widespread, it has a smell of engineering and is not really seductive, its users simply adore to play gurus with obscure shortcuts – even FORTRAN was more sexy.

b) Officially, MacScripters are. scripters, not Objective-C programmers. But I love this site and, for having looked Obj-C forums, I didn’t get the same feeling. For certain sites in french (my language), answers go even to contempt, or at best patronizing --when they come. But I could not come here to complain here if my Objective-C app goes to pieces.

Anyway. tell me if I’m wrong:

An ASOC application is, stricto sensu, a instance of a class (often NSObject). It has instance variables (properties) and methods (handlers). So far, I used only one script per application, so a unique class. I end up with something close enough from procedural programming, with a main unit, procedures and functions. and not reusable at all. So:

¢ Would it be the same in Objective-C? I mean, may my script be “converted” to an instance of an application delegate, sort of @interface MyAppDelegate : NSObject?

¢ Are my handlers convertible into methods of the only appDelegate? Everything I read show that in ObjC, you create new classes or override them very often. Instead of trying to make your table work in ASOC, using tricks to make it show your nice special cells, you “just” create a myNiceTable or myNiceCell class in a separate file and use it.

¢ For those of you who’ve switched from ASOC and Objective-C, is such a “translation” of a script possible, just to begin a new language with a working application as a basis? Is it desirable, or should I reconsider the whole model?

Any advice welcome. I am still in doubt.

Thanks!

Yes, of course. The class structure of ASOC derives from Objective-C

Everything is convertible form ASOC to Objective-C. Even the raw AppleScript code can be executed with NSAppleScript.
The “tricks” are often no tricks but just using the provided capabilities

It’s very helpful for learning to have a working app in ASOC and translate it into Objective-C
The bridged Cocoa methods can be used quasi 1:1, the AppleScript code must be replaced with the ObjC counterpart. You could also easily use ASOC classes in a Cocoa apps

If you want to have fun with programming, learn the language (including the necessary “ugly” C part) and the concept of object oriented programming

This thing works !

  • (IBAction)sayHello:(id)sender;
    {
    NSLog(@“Button pressed”);
    NSLog([sender title]);
    }

@end

Wow. “Making progress”, as Shane would say :lol:

congratulations, you could do it also in one line


- (IBAction)sayHello:(id)sender;
{
    NSLog(@"Button %@ pressed", [sender title]);
}


See? you are my C-guru.

NSLog(@“Button %@ pressed, its tag is %ld”, [sender title],[sender tag]); – More and more!

You know what? That reminds me the Fortran FORMAT statement!

.

Well, in Objective-C, Xcode becomes verbose and does not let you type a single wrong character.

#import <Cocoa/Cocoa.h>

@interface testObjCAppDelegate : NSObject

@property (assign) IBOutlet NSWindow *window;
@property (assign) IBOutlet NSButton *button;
@property (assign) IBOutlet NSArrayController *theController;
@property (assign) IBOutlet NSTableView *gClassTab;
@property (retain) NSMutableArray *className; // I suppose I have to “retain” this? Is it a sort of MoveHHi(myHandle);HLock(myHandle)?

  • (IBAction)setClass:(id)sender;

@end

@implementation testObjCAppDelegate

@synthesize window = _window;
@synthesize button = _button;
@synthesize theController = _arrayController;
@synthesize gClassTab = _tableView;
@synthesize classNames; // Something wrong here. What is the correct way to declare an AS property (=appDelegate instance variable)? What are these @synthesize? sort of “forward declaration”?

  • (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *filePath = [bundle pathForResource:@“Classes” ofType:@“plist”];
    NSMutableDictionary *theDictionary = [NSMutableDictionary dictionaryWithContentsOfFile: filePath];
    NSMutableArray *classNames = [NSMutableArray arrayWithArray: [theDictionary allKeys]];
    }

  • (IBAction)setClass:(id)sender;
    {
    NSLog(@“Button %@ pressed, its tag is %ld”, [sender title],[sender tag]);
    }

@end

There’s no escaping it, but the good news is that the Objective-C parts aren’t very C-ish. The whole target-message thing seemed pretty natural to me, coming from an AS background. But the C…

Not with garbage collection. You basically assign everything.

You’ve added an “s” to the name.

They’re telling the compiler to synthesise accessor methods for the property.

Thank you Shane, you saw what I missed. No compiler cannot guess I mistyped a variable. :frowning:

If I don’t declare a property into the interface part, but only into the implementation part, will this property be visible in IB?

So just:

@interface testObjCAppDelegate : NSObject
@end

would be sufficient? Or not?

You can probably answer that quicker than me…

And the answer is:

. no.

Get used to it :D. Objective-C is a superset of C. Objective-C started out a s pre compiler and in some sort of way still is. Properties, synthesize, implementation, interface, Class, protocol etc… are all compiler instructions. For instance a property + syntesize will just be replaced by a getter and setter method (and methods will be replaced by C functions further in the process before compiling). The more you work with Objective-C the more you will love it and also the more you will hate it. Many times I write C because “I can make that code better in C myself because Objective-C can’t”. When performance becomes an important part of you application you will need C or C++. There is a reason why the core parts of the system and applications are almost never written in Objective-C. Those parts are mostly written in C/C++ like Safari and iTunes for example.

Don’t get your hope up too high if you’ve seen Microsoft’s visual studio’s debugger. Xcode has comporared to Window’s debugging tool still a poor debugging utility. If you’ve only worked with ASOC a whole new world opens.

You sometimes need that in Objective-C as well. Objective-C inherit some drawbacks from C while C++ and C# solved these problems like type casting.

You now have full access to cocoa as well. Core foundation is not Cocoa, it is a C library/API and published under a different library (open source). So it’s a big plus that most of these features are supported by the AppleScriptObjC framework.

See my first answer. I can assure you that less than 50% in the AppStore is actually written in Objective-C. I guess it’s around 10% maybe.

How will you be assured that Apple won’t do that with Objective-C? When I programmed C and Carbon to make Mac OS applications and went to Mac OS X, the Carbon framework that has been used By Adobe, Microsoft and Quark for a very long time (till Leopard; still the core is in C++). Also Carbon was always superior to Cocoa, Cocoa with Objective-C gives the programmer some scripting-feeling which makes late bindings easy and more reliable than with Carbon. Also the goal was with Objective-C and Cocoa to keep the programmer away from the OS and more towards the desktop. Result is coercing paranoia (where casting isn’t possible) if you want something that isn’t in the API (Yet), only we give it a fancy name: ‘Wrapper’.

Well I don’t want to keep you away from Objective-C, I would welcome you to join it. But so many people had their expectations high from Objective-C. Pure Objective-C wise (no core frameworks, no C or C++) there isn’t much that Objective-C can do more than AppleScriptObjC.

I knew that – it’s the big advantage of the bridge (except for methods that use blocks). The problem is not Applescript, ASOC, Objective-C, C++, C or the Intel assembler: the problem is always to have a clean design of the application.:wink: All the problems I have had in ASOC won’t be solved by coding in Obj-C.

Well, no gain, only the pain? Or is it the traditional “Give me C or give me death”?

When I programmed in Pascal, it was “use MC68000 assembler to get this thing done”; In Object Pascal, I was violating the encapsulation to make things work faster, so I know the feeling. Always one layer down.

No, my real problem is code readability. Applescript, ASOC and Obj-C all have, for me, this trait in common. When I say “tell application Finder to set theList to files of theFolder”, I can return two years later to my code and still understand what I did.

No one would have the idea to organize an International Obfuscated Applescript Code Contest. But such a thing exists for C. Is it a sign?

I thought ObjC is to so far from ASOC- I’ll try first to “translate” a small ASOC app (with array bindings in a table) to ObjC, just to keep my mind awake.

Anyway, thank you for your detailed answers, each of you!

No not at all. But you said ‘I don’t like C’; it’s more like a warning that you need a lot of C in Objective-C when you want something that Apple doesn’t have pre-coded for you.

Great! so you’re prepared then that Objective-C isn’t the solution for everything

That’s where comments are for ;). I understand the advantage of AppleScript but it’s the responsibility of the coder to create good readable code. I’ve seen AppleScript code that is more complex than C. Also In my opinion Objective-C is not user friendly at all.
example:

First: AppleScript and C are totally different and can’t be compared. Second: the number of C programmers is more than a thousand times larger. C is multi platform, can be used in micro controllers, different OS (PC, handhelds and tabloids) while AppleScript can only be used in Apple’s desktop OS Since system 7. AppleScript is too simple and basic and one OS oriented and therefore not worthy to create any kind of AppleScript contest.

After all I still think you should take a look at Objective-C because performance wise you have an big improvement. After all ASOC is slow when the framework can’t coerce the code into a full Objective-C class. Like I say, don’t expect something like the solution for all of your ASOC problems.

FWIW, obfuscated AppleScript competitions used to be more-or-less regular occurrences on the AppleScript and MACSCRPPT mailing lists. Entertaining they were, too.

I don’t like C either, but how much of it you have to use depends very much on what you’re trying to do. If a project is interface heavy, chances are the only thing you’ll need to deal with are C-style control structures.

There are a couple of bits of C in AppleScriptObjC Explorer, where some Carbon stuff is required, but otherwise it’s Objective-C with a dash of AS. I didn’t see anywhere that performance required using C. The fact that I had that option was comforting, though.

I’ll happily bow to DJ’s experience on programming matters, but I don’t find Objective-C particularly unfriendly. But I think that’s very much a subjective call, depending on your background. What matters is how friendly you find it.

Thanks and you’re right Shane. Therefore I started with ‘in my opinion’ because what is good for one doesn’t have to be good for another. Clean organized code doesn’t really come with the programming language. Larry flon wrote once “There is no programming language, no matter how structured, that will prevent programmers from making bad programs.”. I think you can tell the same about code organizing. The Problem (personal) is that I mess up Objective-C more often and need more time to re-structure to make it user friendly again before it gets released and archived.

First troubles.

Interface part:

 @property (assign) IBOutlet NSMutableArray *classNames;

implementation part:

 @synthesize classNames;

in applicationDidFinishLaunching:

self.classNames = [NSMutableArray arrayWithArray: [theDictionary allKeys]];
NSLog(@"Array : %@", self.classNames);

Log gives the correct contents, but nothing appears in the table view.

Is the use of “self” ok? If I use it, no error but not text in table view. If I don’t – bang.

what is the IBOutlet for?

the self. syntax uses the synthesized accessor methods which is necessary for key value observing.

Have you set the bindings correctly?

Unlike Shane’s statement I recommend to always retain (for collections) or copy (for NSString/NSNumber etc) object properties even in garbage collection environment and set them with self. to nil in the dealloc method.

An exception are UI element IBOutlets in Mac OS, which could be assigned

As iOS doesn’t support Garbage Collection at all, I would use Memory Management or ARC anyway

The first lines are always the worse.

NSBundle *bundle = [NSBundle mainBundle];
NSString *filePath = [bundle pathForResource:@"Classes" ofType:@"plist"];
self.classNames = [NSMutableArray arrayWithContentsOfFile];
NSLog(@"Array : %@", self.classNames);

logs self.classNames: (null).:mad:

Is "self.classNames = " the equivalence of ASOC “set my classNames to”?

Suddenly ASOC seems a breeze :confused:

I don’t think you want classNames to be an IBOutlet, you can’t have an array in IB that you would be connecting that to (but I tested that and that’s not what is keeping the data from showing up in the table). I suspect you have something in your bindings set up wrong. You should just have your array controller’s content array bound to app delegate with MKP of classNames, and your column in the table should be bound to the array controller with controller key arrangedObjects.

is the root element of the plist file really an array (normally it’s a dictionary)?
Consider also that using arrayWithContentsOfFile the array items are not mutable although the array itself is mutable.

Yes