In part one, we learned about what Wax is and what makes it so awesome. Now, in part 2, we are going to step through making a simple application in Wax that displays a list of currently trending topics on Twitter that can be refreshed with a button.

Final Result:

Step 1 Analyzing AppDelegate.lua

If you look at the current AppDelegate.lua, you should notice a few things. First, you should notice the very first line of the Lua file. This line is the Objective-C class declaration. We create a class called "AppDelegate" that conforms to the "UIApplocationDelegate" protocol. Next, you should see the only method in the file: "applicationDidFinishLaunching". This famous method is called each time the application is launched and the app can now display things on screen. The code in "applicationDidFinishLaunching" is fairly self-explanatory. It creates a new window with a teal background and when places some white text on. However, we want a Twitter client, not a "Hello Lua!" screen. Let's start by creating our UITableViewController.

Step 2 Our Old Friend UITableViewController

Make a new file in the script directory called "TwitterViewController.lua". If you have a good memory, you will remember that to declare a new Objective-C class, we need to use the waxClass function. If you have a really good memory, you will remember that waxClass works like this:

waxClass{"CLASS NAME", "PARENT_CLASS"}

We need a class that extends UITableViewController, so it looks like this:

waxClass{"TwitterViewController", UITableViewController}

Now that we have our class defined, let's handle initialization. In our "init" method, we set the table to be "grouped" instead of "plain", like it is by default. Since we are also going to be displaying a table of trends, it also makes sense for us to initialize a Lua table to hold all of the trends:

Very self-explanatory. We simply set the title in the bar at the top of the screen and then prevent the user from selecting any table rows. We don't want the user selecting any rows because we do not intend to handle that action. You can see what other methods you can call on Apple's documentation page for UITableViewController. Just remember that instead of using properties you have to use the ":property()" and ":setProperty(value)" methods. Press "Run" in the upper-left hand corner of Xcode, and your application should look something like this:

Step 4: UITableViewController Data Methods

Our app launches, which is great, but we want to display some data. To display this data there are a few methods that all UITableViewController's must implement to tell the device what data to display. The first of these methods is "numberOfSectionsInTableView:", which should return the number of groupings that will be displayed in the table. This is very easy with this app because we will only ever need one section, the section with the current trends:

function numberOfSectionsInTableView(self, tableView)
return 1
end

Easy, right? Now we have to implement the "tableView_numberOfRowsInSection" method which tells the device how many rows there will be for a specific grouping. This again is very easy for this app because we only have one section. Remember how we initialized a Lua table in the "init" method? We can simply count the number of items in that table and we will know how many rows this table will need to display:

This uses the Lua short-hand method of counting the number of items in a table. If you are not familiar with Lua tables, here are a few pointers:

What is called a dictionary in most languages is called a table in Lua.

What is called an array in most languages is called a table with ordered numerical keys.

"Arrays" have 1 based indices, as opposed to 0 based indices in just about every other language on the planet.

Next is the "tableView_titleForHeaderInSection" method. This method tells the device what it should display a the title for a grouping. You simply return a string for the specified grouping and then the title magically appears above the table rows:

Pretty simple. Now all we need to do is populate the table with the data we fetch from Twitter's servers. If you are familiar with UITableViewControllers in Objective-C, you will recognize this next method:

This method is a bit more complex. First, we define an identifier that is unique for all cells of the same style, but possibly with different content. In this case we call it "TwitterTableViewControllerCell". Next, we get our instance of a UITableViewCell using a bit of Lua short-hand. Notice the "or" sandwiched between the two method calls. "cell" is set to the value of the first method call if the result of the first method call is not false or nil. Otherwise, "cell" will be set to the result of the second method call. The reason we do this is to save memory. This allows the device to only allocate memory for the 10 or so cells on the screen at one time, instead of the possibly thousands that could exist in the data source. Of course, we won't have thousands of rows to display, but it is still a good habit to be in. Next, we set the content of cell to be the trend that is plucked from the appropriate part of the self.trends "array". We know that this index will never be outside the range of self.trends because we told the device the size of the array in the method "tableView_numberOfRowsInSection". Finally, we return the newly generated cell. If you press "Run" now, it should look something like this:

Step 5 Load Data From Twitter

Now for the fun part that truly showcases Wax's power: loading JSON data from the Internet, or, more specifically, from Twitter's servers. Let's get started by creating a new method called "loadDataFromTwitter". This method should pull the JSON from Twitter's servers and then reload the table with the new data.

function loadDataFromTwitter(self)
UIApplication:sharedApplication():setNetworkActivityIndicatorVisible(true) -- show spinner
wax.http.request{"http://api.twitter.com/1/trends.json", callback = function(json, response)
UIApplication:sharedApplication():setNetworkActivityIndicatorVisible(false) -- hide spinner
if response:statusCode() == 200 then
self.trends = {} -- Reset the list of trends when the trends are refreshed
for index,value in ipairs(json["trends"]) do -- iterate over a table with numerical keys
table.insert(self.trends, value["name"]) -- append the value to the "array"
end
end
self:tableView():reloadData()
end}
end

Yes. It is really that simple. You define the URL to be requested and a callback to be executed when the request is done. Wax automatically identifies that the server is returning JSON and automatically converts the JSON text into a Lua table. This makes showing the network activity indicator (the spinny thing in the top right of the device, near the WiFi signal meter) incredibly easy. The JSON that is returned looks something like this. The key "trends" holds an array of objects that contain the name of the trend and the url to access all tweets with that trend.

After the trend names are stored in the self.trends variable, the tableView is reloaded which re-calls all of data methods that we defined earlier. This results in the trends being displayed in the table, very similar to the final product.

If you try running the app right now, it won't look any different. This is because this method is never called. By calling this method from within "viewDidLoad:", we can make sure we always show the latest trends. Add this line right before the end of the "viewDidLoad:" method:

self:loadDataFromTwitter()

If you hit "Run", the app should look somewhat like this (you may have to wait a few seconds for the trends to load, watch the activity indicator!):

Step 6 Adding a Reload Button

This app is pretty awesome. However, a reload button that allows you to display the freshest trends would be even better. Fortunately, this is really easy.

Let's put a reload button in the upper right hand corner of the screen. Apple actually provides a button that has a refresh icon on it for convenience, so let's use that. Let's start by creating a button in the "viewDidLoad:" method. Add this line before the call to "loadDataFromTwitter":

This creates a UIBarButtonItem that when pressed calles the "loadDataFromTwitter" method on the current object instance. If you want to experiment with other styles, you can find a list here.

Now that we have created a button, we need to add it to our interface. Using a UITableViewController makes this very easy, we simply need to call the "setRightBarButtonItem:" method on the navigation bar object instance like so (this goes after the line I gave you above):

self:navigationItem():setRightBarButtonItem(button)

Now, Twitter trends don't change by the second, so you might not always see a change--but it works, I swear! If you did everything correctly, your completed app should look like this:

Step 7 Extra Credit

Conclusion

I hope you found this tutorial to be a great introduction to Wax. If you want to see more Wax tutorials on a certain subject, be sure to leave a comment and tell me what you are thinking. Who knows, maybe I will take your idea and craft an in depth tutorial from it!