I’ve managed to avoid C and C++ programming for most of my career of 15 years. I’ve dabbled, and then I’ve run back to my favourite languages. Besides, as a web developer there hasn’t often been a need for me to delve that deeply into the machine.
Now that I’m developing iPhone applications, that’s all changing. I’m using PhoneGap to develop my apps, but some of it was buggy, and others just didn’t do what I needed to do. I’m integrating the AdMob and Medialets APIs into my application, which means Objective-C programming. After picking my way around, and continuing on the work my friend Scott McWhirter developed, I think I’ve come up with something that not only works well, but helped me to learn and love Objective-C.
Why I started playing in ObjC
As I integrated Medialets in, I discovered that it has the capabillity of sending custom tracking events so developers of iPhone applications can not only analyze when and where people are using their application, but what they’re doing while they’re using it. I wanted to use this to see how effective parts of my first application are, so I can learn what to change in the future.
Why I Refactored PhoneGap
The way PhoneGap commands worked in the past is it would set “document.location” to an address that looks like “gap:command_name”. If any arguments were supplied, they’d be added on the end separated by colons. But since that is a relative path, it would be added on to the end of your application’s filename. So, since HTML files are loaded locally from within the app’s directory on the iPhone, a GAP command would look like:
So figuring out if a command is being called involved a lot of hackery around stripping out the gap: portion of the URL. Since this was difficult to deal with, and meant there was a lot of re-used code, not to mention commands couldn’t contain colons, or any characters that could potentially be URL encoded, I refactored GAP commands to be their own absolute paths, like so:
When this location is set, a callback within the Objective-C code (called
shouldStartLoadWithRequest) checks the address and determines if the request is a real request and should be allowed to continue, or if it should process the command as a GAP command and disallow the link from being loaded.
So these URLs are never loaded outside of the phone. Once PhoneGap sees a gap:// URL, it parses it as a command request and never attempts to fetch the resource. The benefit of this is that the iPhone’s
URL objects automatically decode the URI parts and escapes any %20-style encodings. It also is a lot simpler to find the name of the command to run, since all it has to do is fetch the URL’s hostname property.
I’ve pushed this to my own fork of PhoneGap up on GitHub if you want to try it yourself. Hopefully these changes get pulled down into the main branch of PhoneGap.
I would also like to make the commands within PhoneGap pluggable, so one doesn’t have to extend one giant if/else block. Instead, it would be nice to have a pluggable framework where you can add commands by inheriting separate classes. I don’t know enough to do this yet, so unless someone else does something similar, it will have to wait.
Certainly I’ve learned quite a bit, and had a great time doing it! I’m really enjoying PhoneGap and iPhone development, and I’m looking forward to adding more as time goes on.