AS3 to Objective-C Cocoa Touch

42-18982424I’ve recently been learning what some people might call real programming, and I’ve found that having an extensive knowledge of AS3 has been more bane than boon. Thus far it’s only served as a reminder of all the cool things one can do with modern programming, but that I cannot seem to do in this strange new language.

What lies ahead is a growing list of migration points and common errors/ warnings that I keep running into. Calling this “Objective-C for Dummies” is too nice. I think “Idiots”, or “AS3 Know-it-all Jerks” is much more appropriate.

TypeCasting

A common and necessary technique in AS3 is typecasting an object as a class so that you can access that class’s methods and properties and avoid compiler errors.

AS3

var params:Object = LoaderInfo( this.root.loaderInfo ).parameter;

OBJ-C

CustomCell *cell = (CustomCell *)[tableView dequeReusableCellWithIdentifier:customID];

Note the pointer(*) used in the cast above, this is not necessary when casting to simple C types, such as int.

int newX = ((int)cell.uv * 320);

Data Structures

While AS3 makes great use of XML and E4X implementation, and obj-c obviously supports xml; the real magic is in using .plist files with an NSMutableDictionary. The NSMutableDictionary class is just as robust as XML in flash, and a .plist file is really just an xml file with a fancy extension that gets viewed differently in Xcode. Go ahead, drag a .plist file into TextEdit, it’s all just xml.

AS3:

var xml:XML;

var loader:URLLoader = new URLLoader();

loader.addEventListener( Event.COMPLETE, xmlComplete );

loader.load( new URLRequest( “some.xml” ) );

private function xmlComplete( e:Event ) : void

{

xml = new XML( e.target.data );

trace( xml.foo ); //outputs “bar”;

}

OBJ-C

NSString *path = [[NSBundle mainBundle] pathForResource:@”someData” ofType:@”plist”];

NSMutableDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];

NSMutableArray *keys = [[dict allKeys] sortedArrayUsingSelector:@selector(compare:)];

NSString *foo = [dict objectForKey:[keys objectAtIndex:1]];

NSString *message = [[NSString alloc] initWithFormat:@”%@”, foo];

NSLog ( message ); //outputs “bar”;

Simple Container

The Sprite class is the all-purpose goto container for just about anything that needs containing or grouping in AS3. It’s obj-c equivalent would have to be UIView, but the difference is that the UIView class can be created in Interface Builder, while the Sprite class can only be created in AS3.

AS3:

removeChild( my_btn );

var shell:Sprite = new Sprite();

this.addChild( sprite );

sprite.addChild( my_btn );

OBJ-C:

[my_btn removeFromSuperview];

UIView *shell = [[UIView alloc] initWithFrame:self.frame];

[self addSubview:shell];

[shell addSubview:my_btn];

Loading Images

AS3:

var loader:Loader = new Loader();

loader.load( new URLRequest( “someImage.jpg” ) );

addChild( loader );

OBJ-C:

UIImage *_image = [UIImage imageNamed:@"someImage.jpg"];

UIImage *_imageView = [[UIImageView alloc] initWithImage:_image];

[self addSubview:_imageView];

Static Methods

While AS3 clearly defines instance and static methods, obj-c calls them instance and class methods.

AS3:

private function someFunction:(someVar:String ) : void

{

}

public static function testFunc() : void

{

trace (“foo”); //outputs: “foo”

}

OBJ-C:

-(void) someFunction:(NSString *)someVar

{

}

+(void) testFunc

{

printf(“foo”); //outputs: “foo”

}

Errors

error: request for member ‘view’ in something not a structure or union

cause: missing import statement in .m file.

error: invalid operands to binary

cause: trying to operate on two different types of numbers( CGFloat & NSUInteger). Cast to other type first.

CGFloat newX = (320 * obj.uv); //–> Doesn’t compile

CGFloat newX = (320 * (int)obj.uv); //–> No error

Warnings

warning: passing argument 1 of ’someFunction:’ from distinct Objective-C type

cause: missing import statement in .h file.

warning: initialization from distinct Objective-C type

cause: return type doesn’t match declaration type, try type casting to your custom class.

CustomCell *cell = [tv dequeueReusableCellWithIdentifier:simpleID];   //<– produces warning

CustomCell *cell = (CustomCell *)[tv dequeueReusableCellWithIdentifier:simpleID];    //<– no warning


About this entry