Here is a quick tour of the Wax framework. By the end you should have a better understanding of how Wax interacts with Objective-C.
In Wax, Cocoa classes are namespaced to keep the global scope clean. To access a class you put a dot . between the framework prefix and the class name.
<div class='code'><pre class="dawn">NS.String <span class="Comment"><span class="Comment">--</span> Returns the NSString class</span>
UI.View <span class="Comment"><span class="Comment">--</span> Returns the UIView class</span>

UI.TableView <span class="Comment"><span class="Comment">--</span> This is just syntactic sugar for the line below.</span>
wax.class["UITableView"] <span class="Comment"><span class="Comment">--</span> This is the raw Wax call</span>
</pre></div>
To see how this works check out the **cocoaNamespace** calls in **APP_ROOT/wax/wax-scripts/init.lua**
To write your own obj-c object, create a new file with a call to waxClass(CLASS_NAME, PARENT_CLASS) at the top.
<div class='code'><pre class="dawn">waxClass{"MyClass", NS.Object}

<span class="Comment"><span class="Comment">--</span> If you need to add protocols, add them like this</span>
waxClass{"MyClass", NS.Object, protocols <span class="Keyword">=</span> {"UITableViewDelegate", "UITableViewDataSource"}}

<span class="Comment"><span class="Comment">--</span> REMEMBER! Protocols need to be added as strings since they are not classes.</span>
</pre></div>
Calling a Lua function with brackets {} instead of parenthesis () (like in the above call to waxClass) is just syntactic sugar for calling a function with a single table as the argument.
<div class='code'><pre class="dawn">waxClass{"MyClass", NS.Object}
<span class="Comment"><span class="Comment">--</span> is equivalent to...</span>
waxClass({"MyClass", NS.Object})
<span class="Comment"><span class="Comment">--</span> ...omitting the parenthesis is much more pretty, so that's how we roll.</span>
</pre></div>
The waxClass function creates an obj-c class via the obj-c runtime. All subsequent functions (within the same file) you add to that Lua file will be automatically added to your new class as instance methods.
For waxClass functions, the first argument must be self. This is how Wax mimics obj-c's object orientated model.
waxClass{"MyClass", NS.Object}
-- Notice the first argument is self... this will hold an instance of MyClass
function storeWords(self, words)
self.words = words
-- Wax creates a super variable on the self object.
-- Use that to call a method on the object's super class.
self.super:words(self)
end
Use a colon : instead of a dot . when you call any obj-c method. This secretly passes the calling object in as the first argument to the method.
<div class='code'><pre class="dawn"><span class="Comment"><span class="Comment">--</span> A method called with a colon : in Lua ...</span>
UI.Application:sharedApplication()

<span class="Comment"><span class="Comment">--</span> ... is equivalent to this</span>
UI.Application.sharedApplication(UI.Application)

<span class="Comment"><span class="Comment">--</span> So we just use the colon : to keep this DRY and readable!</span>
</pre></div>
You can dynamically create member variables for any obj-c object using the dot . operator. Unlike the colon : operator (used to call methods on an obj-c class/instance) the dot . operator dynamically creates member variables on the Lua side of the object (The obj-c side of the object has no knowledge of these variables). The member variables are available throughout the lifetime of the object.
<div class='code'><pre class="dawn"><span class="Comment"><span class="Comment">--</span> A method called with a colon : in Lua ...</span>
<span class="Keyword">local</span> view <span class="Keyword">=</span> UI.View:init()

view.someRandomVariable <span class="Keyword">=</span> "YEAH!"
<span class="Comment"><span class="Comment">--</span> You can assign anything to an instance and it will stick around</span>
</pre></div>
If an obj-c method takes multiple arguments, the method call uses underscores _ instead of colons like in obj-c.
In obj-c...
<div class='code'><pre class="dawn">[UIAlertView initWithTitle:@"title" message:@"message" delegate:nil];
</pre></div>
With Wax...
<div class='code'><pre class="dawn">UI.AlertView:initWithTitle_message_delegate("title", "message", <span class="Constant">nil</span>)
</pre></div>
Wax will try and coerce obj-c objects into Lua. It also does the reverse, if an obj-c methods takes an NSString argument, you can just pass it a lua string.
<div class='code'><pre class="dawn"><span class="Keyword">local</span> fileManager <span class="Keyword">=</span> NS.FileManager:defaultManager()
<span class="Keyword">local</span> contents <span class="Keyword">=</span> fileManager:directoryContentsAtPath(".")
<span class="Comment"><span class="Comment">--</span> directoryContentsAtPath returns an NSArray, but Wax turns this into a Lua</span>
<span class="Comment"><span class="Comment">--</span> table, which is totally cooler.</span>

<span class="SupportFunction">print</span>(contents[<span class="Constant">1</span>]) <span class="Comment"><span class="Comment">--</span>> "info.plist"</span>

<span class="Comment"><span class="Comment">--</span> NSDictionaries become Lua tables</span>
<span class="Comment"><span class="Comment">--</span> NSArrays and NSSets become Lua tables</span>
<span class="Comment"><span class="Comment">--</span> NSStrings become Lua strings</span>
<span class="Comment"><span class="Comment">--</span> NSNumbers become Lua numbers</span>
</pre></div>
Sometimes you don't want an obj-c object to be coerced, for that use the toobjc method.
<div class='code'><pre class="dawn"><span class="Comment"><span class="Comment">--</span> if you are trying to call an NSString method, this will fail ...</span>
<span class="Keyword">local</span> string <span class="Keyword">=</span> "a string"
string:capitalizedString()
<span class="Comment"><span class="Comment">--</span> ... because string is coerced into a Lua string</span>

<span class="Comment"><span class="Comment">--</span> This will force string to behave like an NSString</span>
toobjc(string):capitalizedString()
</pre></div>
Enums, like UITableViewStylePlain, are a bit tricky. For now the most commonly used ones are declared in APP_ROOT/wax/wax-scripts/enums.lua. In the future I hope to get BridgeSupport working for the iPhone so all enums & structs can be created automatically.
Structs are also tricky, the most common ones are decalred in APP_ROOT/wax/wax-scripts/structs.lua. It is easy to add structs by following the pattern found in the structs.lua file.
<div class='code'><pre class="dawn">wax.struct.create("CGRect", "ffff", "x", "y", "width", "height")

<span class="Comment"><span class="Comment">--</span> The creates a global function called CGRect that takes 4 float arguments,</span>
<span class="Comment"><span class="Comment">--</span> the second argument "ffff" is what defines the argument types.</span>

<span class="Keyword">local</span> rect <span class="Keyword">=</span> CGRect(<span class="Constant">1</span>, <span class="Constant">2</span>, <span class="Constant">3</span>, <span class="Constant">4</span>)
<span class="SupportFunction">print</span>(rect.x) <span class="Comment"><span class="Comment">--</span>> 1</span>
rect.x <span class="Keyword">=</span> <span class="Constant">200</span>
<span class="SupportFunction">print</span>(rect.x) <span class="Comment"><span class="Comment">--</span>> 200</span>
</pre></div>
Recent Posts