On Porting from iPhone to Netbook with Flex - Understanding the Syntax of ActionScript and MXML

by Ryan Green

Flex BurgerI've spent most of my career on the web. Well, my first real job was as busboy at a local mexican hole-in-the-wall restaurant (love the salsa.) Then as proud crew member of a certain fast-food burger joint with golden arches (click here to skip to the meat of this post), then, as up and coming young web designer. It is amazing the job you could land in the dot-com bubble with some decent photoshop know-how and a copy of Microsoft Frontpage...

Anyhow, what I quickly learned in my stint as web master, besides the art of pixel perfect nested HTML table layouts so that my webpages could load inside the 1990's on a 28.8 baud modem, was that if you wanted to give your customers any value besides a relatively accurate re-creation of their 4 page full-color brochure, you needed to know databases and some form of server side scripting.

I chose Cold Fusion. At the time this was due to the fact that it was the only book in our little office that didn't have the letters 'CGI' and 'Perl' in the title. Cold Fusion provided some nice tag based syntax for connecting with a database and displaying tractor parts in a webpage. Then came Javascript and DHTML and VBScript and PHP and then, at last, Actionscript 1 & 2.

Now, lest you fear I die a quick death stuffed to the gills with obscure scripting language knowledge, Actionscript 3 arrived with Flex just in time to spare me the wrath of Java nerds hailing the death of ColdFusion and other "non-languages." The language of the User Interface has steadily matured into Object-Oriented like syntax and smarter uses of XML to define the UI, and the "real-programmers" have moved native with Objective-C/C++/C#/C-flat and C#-minor. Oh, and don't forget Java on that little mobile platform called Android... and how dare I forget ruby and python.

All this to say that, in this day-and-age, we face a fragmented amalgamation of languages and platforms all vying for title of "most-awesome-real-language."

Well, my nomination for new entrant into the "real-language" lexicon is Actionscript/MXML, a syntax that gives Javascript its Object-Orientation and the HTML tag actual namespaces and custom tag names.

Syntax Differences in Objective-C/C/C++ and Actionscript 3

Actionscript is a product of the ECMA Script specification which is, in turn, part of the C programming language family. In basic syntax (operators, conditional statements and enumeration), Objective-C and Actionscript are almost identical.

  Objective-C/C/C++ Actionscript 3
Calculation +, -, /, *, ++ (increment), -- (decrement), % (modulo) Same
Assignment = Same
Comparison ==, !=, ===, !==, >, <, >=, <= Same
Comment /* */, // Same plus <!-- --> for MXML
Logical &&, ||, ! Same
Null

nil (use to compare with Objective-C objects)
Nil (use to compare with Objective-C classes)
NULL (use to compare with everything else)

null
If Statement if(condition) {
  //when condition evaluates to true
}
else if(condition2) {
 //when condition2 evalutates to true
}
else {
  //when condition and condition2 evaluate to false
}
Same
Switch/Case

switch(expression) {
  case value1:
   //statements
   break;
  case value2:
   //statements
   break;
  default:
   //statements
   break;
}

Same
Fast Enumeration for(Type newVariable in collection) {
  //statements
}
for(var value:Type in collection) {
  //statements
}
Do / While while(expression) {
  //statements
}
Same
For for(int value = start; value <= end; value++) {
  //statements
}
for(var value:int = start; value <= end; value++) {
  //statements
}
Ternary return (i > 0) ? true : false; Same

Where the languages start to diverge is in how they instantiate and declare variables and methods and how they message objects.

Primative Types

  Objective-C/C/C++

Actionscript 3

    Data Type Documentation
Boolean BOOL mine = YES;
BOOL mine = NO;
var mine:Boolean = true;
var mine:Boolean = false;
Integer int i = 1; var i:int = 1;
Float float pi = 3.14; var pi:Number = 3.14;
String NSString *fname = @"Ryan"; var fname:String = "Ryan";

Declaring Classes

  Objective-C/C/C++

Actionscript 3

Documentation Declaring Classes Documentation Declaring Classes Documentation
Declare Class //-- File ClassName.h //import dependencies #import "dependent.h"; @interface ClassName : SuperClass { @public|@private|@protected|@package //declare instance variables Type variableName; } //declare properties @property (nonatomic, retain) variableName; //constructor -(id)init; //declare instance methods -(Type *)forThisObject: (Type *)obj makeSize: (int)size; //declare static methods +(void)doSomething: (Type *)thisObject; @end //-- File ClassName.m @implementation ClassName //generate getter/setters @synthesize; //implement instance methods -(id)forThisObject: (id *)thisObject makeSize: (int)size { } //implement static methods +(id)doSomething: (id *)thisObject { } @end

//-- File ClassName.as
package {

//import dependencies
  import dependant;
  public class ClassName extends SuperClass {
    //declare instance variables
   public|private|protected var variableName:Type;
   //constructor
   public function ClassName():void {
    }
   //declare instance methods
   public function makeSize(obj:Type, size:int):Type {

      //implementation
   }
   //declare static methods
   public static function doSomething(
obj:Type):void {
     //implementation
    }
  }
}

Declaring Variables

  Objective-C/C/C++

Actionscript 3

    Declaring Variables Documentation
Instance Variables (accessible outside class)

//-- File ClassName.h
@interface ClassName {
  Type *variableName;
}
@property (nonatomic, retain) variableName;
@end

//-- File ClassName.m
@implementation ClassName
  @synthesize variableName;
@end


//-- File ClassName.as
package {
  public class ClassName {
    private var _variableName:Type;
   public function get variableName():Type {
     return _variableName;
   }
   public function set variableName(value:Type):void {
     _variableName = value;
   }
  }
}


or

//-- File ClassName.as
package {
  public class ClassName {
    public var variableName:Type;
  }
}

Static Class Variables

//-- File ClassName.h
@interface ClassName {
  Type *variableName;
}
@end

//-- File ClassName.m
@implementation ClassName
  static Type *variableName;
  +(Type *)variableName {
    return variableName; }
  +(void)variableName: (Type *)newVar {
    variableName = newVar;
  }

@end

//-- File ClassName.as
package {
  public class ClassName {
    public static var variableName:Type;
  }
}
Local Variables

(int) i;

or

(NSString *) fname;

var i:int;

or

var fname:String;

Access Properties obj.propertyName;
obj->propertyName;
obj.propertyName;

 

Implementing Methods/Functions

  Objective-C/C/C++

Actionscript 3

    Declaring Functions Documentation
 

@interface {}
-(Type *) methodName: (Type *)arg1 byArg2: (Type *)arg2;
@end

@implementation ClassName
-(Type *) methodName: (Type *)arg1 byArg2: (Type *)arg2 {

}
@end

public function methodName(arg1:Type, arg2:Type):Type { }

Implementing Getters/Setters

  Objective-C/C/C++

Actionscript 3

    Getter/Setter Documentation
 

@synthesize propertyName;

or

-(Type *) propertyName { return propertyName; }
-(void) propertyName: (Type *)newVal { propertyName = newVal; }

/* getter/setter functions may not have the same name as private instance variables */

private var _propertyName;
public function get propertyName():Type {
   return _propertyName;
}

public function set propertyName(value:Type):void {
  _propertyName = value;
}

Class Instantiation

  Objective-C/C/C++

Actionscript 3

  Type *class = [[Type alloc] init]; var class:Type = new Type();

Handling Basic Data Types

In general Actionscript objects are always mutable and like Objective-C, Actionscript is reflective.

Reflection

  Objective-C/C/C++

Actionscript 3

Documentation

Reflection Documentation (examples referenced)

Class Declaration Class cls = NSClassFromString(@"Foo");
id foo = [[cls alloc] init];
var class:Class = getDefinitionByName("Foo") as Class;
var foo:Class = new class();
Call Dynamic Method

SEL selector = NSSelectorFromString(@"hello");
[foo performSelector:selector withObject:nil];

foo["hello"]();

Handling Strings

  Objective-C/C/C++

Actionscript 3

Documentation NSString Class Documentation String Class Documentation
Declaration NSString * str = @"The quick brown fox"; var str:String = "The quick brown fox";
Concatenation NSString * str2 = [str stringByAppendingString: @"jumped ..."]; str = str + " jumped over the lazy river";
Replace NSString * final = [start stringByReplacingOccurancesOfString: @"find" withString: @"replace"]; str = str.replace('find', 'replace');
Search NSRange *range = [myString rangeOfString: @"string to find"];
//returns {NSNotFound, 0} if not found
var idx:int = str.indexOf('string to find');
// returns -1 if not found;
Substring NSString *str2 = [str substringWithRange: NSMakeRange (0, 1)]; var sub:String = ("string").substr(0, 1);
trace(sub); //<-- outputs "s"
Comparison

NSComparisonResult result = [str compare: @"first"];
// result == YES

var str:String = "first";
var b:Boolean = (str == "first");
trace(b); //<-- outputs "true"

Handling Arrays

  Objective-C/C/C++ Actionscript 3
Documentation

NSMutableArray Class Documentation

Array Class Documentation
ArrayCollection Class Documentation

Declaration

NSArray *a = [[NSArray alloc] initWithObjects: @"apple", @"orange", @"grape"];
NSMutableArray *b = [[NSMutableArray alloc] init];
[b addObjectsFromArray: a];

or
NSMutableArray *a = [[NSMutableArray] alloc] init];

var a:Array = ["apple","orange","grape"];
or
var a:Array = new Array();

Add Element at end [a addObject: @"lemon"]; a.push("lemon");
Add Element at beginning [a insertObjectAtIndex: @"lemon"]; a.unshift("lemon");
Remove Element at end [a removeLastObject]; var fruit:String = a.pop();
Remove Element at beginning [a removeObjectAtIndex: 0]; var fruit:String = a.shift();
Access Element at Index [a objectAtIndex: 0];

var a:Array = ["apple", "pear"];
trace(a[0]); //<-- outputs "apple"
trace(a[1]); //<-- outputs "pear"

Remove Element at Index [a removeObjectAtIndex: 1];

var a:Array = ["apple", "pear", "peach"];
a.splice(1, 1);

Length of Array [a count];

var a:Array = [0, 1, 2, 3, 4];
trace(a.length); //<-- outputs "5"

Handling Dictionary Objects

  Objective-C/C/C++

Actionscript 3

Documentation

NSMutableDictionary Class Documentation

Object Class Documentation
Dictionary Class Documentation

Declaration NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjects: [[NSArray alloc] initWithObjects: @"Ryan", @"Green"] forKeys: [[NSArray alloc] initWithObjects: @"firstname", @"lastname"]
or
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
var object:Object = {firstname:"Ryan", lastname:"Green"};
or
var object:Object = new Object();
Set Object for Key [dict setObject: @"D" forKey: @"middleinitial"]; object.middleinitial = "D";
or
object["middleinitial"] = "D";
Remove Object for Key [dict removeObject: @"D" forKey: @"middleinitial"]; delete object.middleinitial;
Get Object By Key [dict objectForKey: @"middleinitial"]; if(object.hasOwnProperty('middleinitial')) {
 return object.middleinitial;
}

Terminators / Cleanup

Ahh, now you've caught me. Actionscript is one of those languages that does not allow for direct garbage collection. However, if you successfully release all references to your object, Flash promises to garbage collect... eventually.

  Objective-C/C/C++

Actionscript 3

Release Memory [object release];

delete object;

Putting it All Together

  Objective-C/C/C++

Actionscript 3

Favorite Foods interface

//-- File FavoriteFoods.h
@interface FavoriteFoods : NSObject {
  NSMutableArray *foods;
}

@property (nonatomic, retain) *foods;
-(void)init;
-(void)addFavoriteFood:(NSString *)food;
+(BOOL)badForMe:(NSString *)food howMany: (int)count;
@end



Favorite Foods class //-- File FavoriteFoods.m
@implementation FavoriteFoods
  @synthesize foods;
  -(id)init {
   foods = [[NSMutableArray alloc] init];
   return self;
  }
  -(void)addFavoriteFood:(NSString *)food {
   [foods addObject: food];
  }
  +(BOOL)badForMe:(NSString *)food howMany: (int)count {
   if([food compare: @"1 pound hamburger"] == YES) {
     switch(count) {
      case 0:
      case 1:
        return NO;
      break;
      default:
        return YES;

     }
    }
   else {
     return NO;
    }
  }
  -(void)dealloc {
   [foods release];
  }
@end
//-- File FavoriteFoods.m
package {
  public class FavoriteFoods {
   public var foods:Array;
   public function FavoriteFoods():void {
     foods = new Array();
    }
 public function addFavoriteFood(food:String):void {
   foods.push(food);
   }
 public static function badForMe(food:String, count:int):Boolean {
   if(food == "1 pound hamburger) {
    switch(count) {
      case 0:
      case 1:
       return false;
      break;
      default:
       return true;

       }
     }
     else {
      return false;
     }
    }
  }
}
Manage Favorite Foods class //-- File ManageFavoriteFoods
...
#import "FavoriteFoods.h";
...
FavoriteFoods *favorites = [[FavoriteFoods alloc] init];
NSString *food = @"1 pound hamburger";
[favorites addFavoriteFood: food];
printf([FavoriteFoods badForMe: food howMany: 5]); //prints YES
[favorites release];
//-- File ManageFavoriteFoods
...
import FavoriteFoods;
...
var favorites:FavoriteFoods = new FavoriteFoods();
var food:String = "1 pound hamburger";
favorites.addFavoriteFood(food);
trace(FavoriteFoods.badForMe(food, 5)); //traces true;
delete favorites;

Ok, so this was a pretty high level flyby of Actionscript syntax. What I think you'll find in using AS3 is that it is very Javascript-like and less verbose than Objective-C, however when combined with the Flex SDK, I believe you'll find a corollary in Flex to most Objective-C features.

What I found in a previous porting project from iPhone and Objective-C to Flex and AS3, was that in many cases the logic and syntax of the non UI code (that is class structure, logic and graphic APIs) was a nearly direct port. I found myself copying and pasting C code and simply fixing the syntax. This is the power of a code base like Flex over classic Flash development. In Flex, there is no timeline or stage in which to store snippets of code in frames and under buttons. Because of this, Flex can offer 'real-programmers' a much more comfortable transition into flash programming through Object-Oriented syntax and a class based code structure.

Stay Tuned, in my next installment we'll be getting into the meat of the SDKs and comparing/contrasting UI patterns and implementation differences so that you have a path for porting User Interface from Cocoa to Flex.

If you missed part 1 of this series, I welcome you to check it out. In the first article I introduce Flash and provide a high-level comparison between the Cocoa and Flex SDKs.

3
Average: 3 (1 vote)

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Posted On : September 21, 2010 - 11:59
Offline
Last seen: 16 weeks 20 hours ago
Joined: Dec 29 2009
Points: 4139

Nice article that provides insight into ActionScript 3. Thanks! I would point out that the column(s) labeled Objective-C/C/C++ are really *only* Objective-C, as C++ has a different format for defining clasess, and certain things like classes cannot be accomplished in C. The only table for which the column applies to all three is the very first, "Syntax Differences" and some of the second, "Primative Types" (NSString is not in C/C++, but the other types are).

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.