Reusable Components

There was a lot of grumbling when Titanium 1.8 came out, and CommonJS was introduced. People had built apps using the best practices of 1.7, but suddenly there were a whole new set of best practices. It took me a bit to get used to the syntax, but once I got over that hurdle, the lightbulb turned on. Coming from a Flex background, it dawned on me that I could finally make my Titanium apps more object-oriented.

I keep seeing code in the Q&A that frankly makes me cringe. The strict-typing in actionscript forced me to use some great best practices, and CommonJS lets us move closer to that style of coding.

I figured that the most common UI element that gets reused in any app is the humble TableViewRow. So, let’s look at my BeerRow module:

The first thing you’ll notice is the retina variable I set once in the module. Like the comment implies, most Ti.Platform calls are expensive, so you should do your best to minimize those calls.

Next, there’s the BeerRow method, which takes a beer object as a constructor parameter, and returns a TableViewRow. The code inside is pretty standard, creating a row, adding a picture and a title. This row is overloaded though, where I add the getter and setter methods pushBeer and pullBeer, respectively. Since the actual ImageView and Label objects won’t be accessible to the outside world, the pushBeer method has to update those for us. Note that the slightly unconventional names are because you can’t add methods that start with “get” or “set” to Titanium proxy objects.

Last, we assign our BeerRow method to module.exports, because, well, that’s how CommonJS modules work. I really like the coding conventions of actionscript, where object classes are UpperCamelCase, and variables are lowerCamelCase, so you’ll notice that my filename and constructor methods are both BeerRow.

So, we have this wonderful row, how do we use it? It’s actually very easy to do:

First, we use require() to include our module. Again, I give my variable the UpperCamelCase so I know it’s the object itself, and not an instance of the object.

Next, I’m looping over my beers array and creating a row for each one. We create an instance of our BeerRow using new BeerRow(beers[i]).

Just after that, I add a click event listener. Inside that event listener, you can see I call my custom getter method, pullBeer, to display the name. Typically, you would probably take that beer object and use it in the constructor of a new window.

I add the row to my array of rows, and then set the TableView’s data to that array. Now you’re playing with code-reuse!

You can find the full source-code for this sample application in my blog-samples project on GitHub.

Loop labels with Titanium

I recently ran into a situation where I needed to compare values inside two associative arrays. I ended up having to nest two different loops, but wanted to optimize performance by breaking the inner loop when I found what I was looking for. A bit of searching, and I found what I was looking for… Loop Labels. They’re really easy to do and understand, so here’s a simple loop label example, and what the console debug output looks like:

Mobile App Testing – Picking the right test devices

I figured that it would be great to kick off my new-found motivation to blog with a post going over how I do mobile testing. You have to do testing, it has a high cost of entry, and can be intimidating. Let’s walk through how I do it as a entrepreneur/consultant:

First, let’s establish some basic ideas:

  1. If you’re not testing on-device, you’re not testing. While handy for spot-testing as you code, the iOS Simulator is unrealistically fast, and the Android Emulator is slow, buggy, and difficult to use. Also, some things won’t work or break until you test with a real build, like push notifications or Google Maps API keys.
  2. If you want to test your app on every current iPhone, you currently have 4 devices to test on. If you want to do that for Android, you will want to win the lottery, and rent a warehouse.
  3. Other things are harder to sim/emulate, like available processor & memory on a phone that has real-world usage. There’s a lot more happening on a phone that has active email/calendar/push connections, and has other apps open in the background.

That being said, all is not lost. I’ve formed an effective strategy to maximize my testing coverage. First off, I buy the latest iPhone when it comes out. That’s the easiest decision, since we’re talking one phone per year. Android requires a bit more clever thinking, though.

  1. Buy new Nexus devices. Google actually keeps these phones up to date on reasonable schedules, unlike any other Android phones on the market. If you look at the recent Nexus history, the Nexus One, Nexus S and Galaxy Nexus, I bought the Nexus One, skipped the Nexus S, and bought a Galaxy Nexus. This gave me a “latest & greatest” OS to work on, all the time. I’ll probably skip the next Nexus device, unless there’s some significant deficiency, either on the hardware or software side.
  2. Buy used “carrier” devices. Cracked screen? Big ugly gash in the frame? As long as it’s functional, who cares? Craigslist and eBay are great places to find cheap phones.
  3. Diversify brands and models. I’m sure you have a favorite, but the sad reality is that the manufacturers like to put their big, ugly thumbprints on their phones. HTC Sense, MotoBLUR, and Samsung TouchWiz introduce nuances and bugs that will be unique to their phones.

Personally, I try to buy one phone from each manufacturer for each major version of Android. I try to stick to the most popular model for each, because the odds are in my favor that I’ll have the phone that my client has. If you’re keeping count, that means that each calendar year I plan on buying one new iPhone, one new Nexus, and 3-4 used Android phones.

The hidden problem I encountered was that it’s hard to carry around so many phones. I looked for multiple-phone carrying cases, but couldn’t find anything. I eventually figured out that Pistol Cases (Amazon Affiliate link) are perfectly sized to hold a bunch of phones.

Yes officer, that’s my pistol case. No sir, I have it because Android is fragmented and I’m a developer.

I just cut out slots in the foam, and used a bit of spray glue to attach the foam to the case. Cost me $10 at my local sporting goods store, plus the glue. You can see it’s holding 8 phones, a MiFi, and still has room for three more. Luckily, while Android phones might do everything else differently, they all share the same USB/Charing cable. I could carry everything I need in that one little case, at least for the next year or so.