Lua is a powerful, fast, lightweight, embeddable scripting language.
Lua combines simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics. Lua is dynamically typed, runs by interpreting bytecode for a register-based virtual machine, and has automatic memory management with incremental garbage collection, making it ideal for configuration, scripting, and rapid prototyping.
It’s that exotic, super-fast scripting language that very few use, right? Partially right. It’s extensively used in the gaming industry (e.g. World of Warcraft) usually together with C++.
Lua comes with a console, which is great tool for fast experimenting of logic and syntax.
All fine and dandy, but how can this help me on iOS development? Stefan found the right answer: iPhone Wax .
Wax is a framework that lets you write native iPhone apps in Lua. It bridges Objective-C and Lua using the Objective-C runtime. With Wax, anything you can do in Objective-C is automatically available in Lua!”
Corey Johnson, main guy behind Wax
As anyone with iOS development experience knows, Obj-C is very strict about classes, requiring a certain mindset to write good, maintainable and modular applications. Wax doesn’t alter this approach at all.
Memory management is another worry that goes away in Wax, because of the automatic garbage collection.
By this point, Wax looked completely different than any other write-quick-iphone-appsgimicks out there, including PhoneGap, Titanium, Rhomobile, Corona SDK. Do note that I mention “iPhone apps”, since the result of Wax is not cross platform. Well, a solid application should take advatage of the hardware platform and the only part that can be cross platform is the interface, even that within certain limits.
Wax looked good in theory. A UITabBarController is a UITabBarController, a delegate is a delegate, 3rd party libs work how they are intended to (Facebook, ASIHTTPRequest, custom written ones). Now let’s see it in practice.
I gave Wax a run-around for 1 week. During that time I tried using most of the UITouch, Cocoa elements and some 3rd party libraries. The results were good. The interface is just as responsive as building directly in Obj-C.
After that test week, the decision of using Wax for the rest of app development seemed obvious, even more, Wax seems like a valuable addition to the development cycle.
Here’s a small benchmark of memory usage by the same application, written in Wax and in Obj-C. The application used is Fortune Crunch from Mark’s tutorial on MobileTuts+.
Objective-C code (can be seen in the source code of the tutorial too):
// FortuneCrunchAppDelegate.h // #import <UIKit/UIKit.h> @class FortuneCrunchViewController; @interface FortuneCrunchAppDelegate : NSObject <UIApplicationDelegate> { UIWindow *window; FortuneCrunchViewController *viewController; } @property (nonatomic, retain) IBOutlet UIWindow *window; @property (nonatomic, retain) IBOutlet FortuneCrunchViewController *viewController; @end // FortuneCrunchAppDelegate.m // #import "FortuneCrunchAppDelegate.h" #import "FortuneCrunchViewController.h" @implementation FortuneCrunchAppDelegate @synthesize window; @synthesize viewController; #pragma mark - #pragma mark Application lifecycle - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. // Add the view controller's view to the window and display. [self.window addSubview:viewController.view]; [self.window makeKeyAndVisible]; return YES; } - (void)dealloc { [viewController release]; [window release]; [super dealloc]; } @end // FortuneCrunchViewController.h // #import <UIKit/UIKit.h> @interface FortuneCrunchViewController : UIViewController { IBOutlet UIButton *fortuneCookieButton; IBOutlet UILabel *fortuneLabel; } @property(nonatomic, retain) IBOutlet UIButton *fortuneCookieButton; @property(nonatomic, retain) IBOutlet UILabel *fortuneLabel; -(IBAction)crunchCookie:(id)sender; @end // FortuneCrunchViewController.m // #import "FortuneCrunchViewController.h" @implementation FortuneCrunchViewController @synthesize fortuneCookieButton; @synthesize fortuneLabel; // This method changes the cookie image when the button is pressed: -(IBAction)crunchCookie:(id)sender { NSLog(@"In crunchCookie"); [fortuneCookieButton setImage:[UIImage imageNamed:@"cookie-crunched.png"] forState:UIControlStateNormal]; fortuneLabel.hidden = NO; } // These methods are related to memory management: - (void)viewDidUnload { [fortuneCookieButton release]; fortuneCookieButton = nil; } -(void)dealloc { [fortuneCookieButton release]; [fortuneLabel release]; [super dealloc]; } @end-- AppDelegate.lua
waxClass{"AppDelegate", protocols = {"UIApplicationDelegate"}} require "FortuneCrunchViewController" function applicationDidFinishLaunching(self, application) local frame = UIScreen:mainScreen():bounds() self.window = UIWindow:initWithFrame(frame) self.window:setBackgroundColor(UIColor:whiteColor()) local fc = FortuneCrunchViewController:init() self.window:addSubview(fc:view()) self.window:makeKeyAndVisible() end -- FortuneCrunchViewController.lua waxClass{"FortuneCrunchViewController", UIViewController} function crunchCookie(self, sender) self.button = self:view():viewWithTag(1) self.button:setImage_forState(UIImage:imageNamed('cookie-crunched.png'), UIControlStateNormal) self.label = self:view():viewWithTag(2) self.label:setHidden(false) end function init(self) self.super:initWithNibName_bundle("FortuneCrunchViewController", nil) return self end
Both projects use the same .xib created in Interface Builder, per the tutorial. Bellow are 2 screen-shots of the memory usage.
Objective-C
As expected, Wax has a small foot-print.
Most of the people dislike the syntax of Obj-C and it does slow down development. Speed and maintainability are of great value for new apps and here is an awesome alternative!