Pitfalls - Getting Dojo onto iPhone and Android with PhoneGap
Now that I’ve cut my teeth on web development with my new-ish website, I’ve decided to go dental and start making some phone apps using HTML5, CSS, and JavaScript. After having played around with jQuery for my website, I realized that the code began to grow to the point where just managing it was becoming a tough issue. For a large app, a framework (and not just a library) is necessary, in my view. For this, Dojo, I choose you!
Dojo is a lot different from jQuery-land. While plugins in jQuery are extensions of the jQuery object, Dojo’s approach in the latest 1.7 version has been a game-changer, opting for the AMD (Asynchronous Module Definition) structural approach. I’m not going to go into the specifics of AMD (especially since I’m still learning it!), but Dojo has a fantastic documentation section complete with tutorials and API glossary hotness.
How to get HTML into an iPhone or Android app, you ask?
There are a few SDKs out there to get your webapp into the App Store or Android Market, one of them being PhoneGap. Now, if you want to make games specifically be warned! PhoneGap puts your app into a WebView, essentially a chromeless browser window, and wraps it with native code, exposing things like the phone or tablet’s accelerometer, camera, and GPS to your JavaScript. But for making games with <canvas>
or WebGL, I’m learning, WebViews are slow. You’d probably be better off with another method — some I’ve seen tossed around are ImpactJS, CocoonJS, directCanvas, and Game Closure. These utilities claim to accelerate your mobile HTML code by leaps and bounds, and are worth looking into.
With that said, I’m not going to show you how to get PhoneGap running on your phone with Dojo. There are plenty of articles about that already. I will say be attentive if you’re using Dojo 1.7, though.. it’s fairly new and many tips out there still use the old and radically different 1.6 syntax. Instead, I’m going to tell you about a few pitfalls I ran into while getting Dojo onto my iPhone and Android phones, that aren’t heavily documented on the web.
JavaScript Obfuscation
Since PhoneGap wraps your webapp in a native code container, a clever person will be able to open that container and see/copy all your code. I tested this by viewing the /Applications directory on my iPhone. You can actually use a terminal to peek inside apps, and your PhoneGap app will expose all the files in your www directory in plaintext. So obfuscation could be important to protect your hard work.
Dojo from a CDN vs. a Local Copy
When dropping Dojo into your HTML file, you can choose to either drop a script tag that references a server that hosts the library online, or you can download a copy of the library and reference it in the script tag locally. For mobile apps it can be a tricky decision - you might want your users to be able to use your app when off the grid, but since Dojo can be more than 50MB (!), you might be hesitant to pack your own copy. I chose to stay local. Doing so gives me more control over Dojo’s options, and I’ll explain how you can reduce that filesize in #5.
Dojo’s Option, async:1
, Works on iPhone, but not Android
Dojo 1.7 introduced the ability to load modules asynchronously, allowing developers to load into the app only what they needed. This gives us the ability to reduce the load and bandwidth usage on servers and end-user devices, and makes our code tight and light. Basically, the application loads only the base Dojo modules at first, and as your app requires other modules, they are loaded on demand from either the server or the local copy. This works swimmingly on iPhone, but unfortunately, not on Android. There seems to be an inherent problem with Android loading scripts asynchronously, as Dojo intends. Therefore, you have to use the Dojo Build Script, which I touch on in the next section.
Dojo’s Build Script Saves the Day
Usually a developer would use Dojo 1.7+ to load modules in as needed, but there are great advantages to using the build script. It’s a tool run via command-line that, using an install of node.js or Java, allows you to specify each module you use in your application in order to combine and minify those files, and only those files, into one script. Using that script instead of the usual dojo.js
script allows your app to work perfectly and makes it light. It also makes your Android async problems disappear. No scripts are dynamically loaded; they’re all included in the script you built. The build script has a number of options, including being able to parse your HTML file for required modules. That didn’t work for me, so I found it essential to create a profile, as Björn explains. Dojo has more documentation on your build script options. If you want to follow what worked for me, navigate to the buildscripts folder and use the command ./build.sh action=release profile=profiles/myBaseplus.profile.js -r
, replacing ./build.sh
with build.bat
if you’re on Windows and myBaseplus.profile.js
with the profile of your making, and you’ll be A-OK.
deviceready
vs. dojo/domReady!
Web developers know they shouldn’t start their JavaScript before the DOM is ready because the content of the page hasn’t loaded in order to be manipulated by their code yet. Dojo has a built-in module to make sure you can fire your code when the DOM is loaded, and that’s by including the module, dojo/domReady!
, which is very similar in function to jQuery’s $(document).ready()
call.
PhoneGap has an event of its own that fires when all the device’s native gadgets are available to use in JavaScript, and that’s the deviceready
event. They set up your sample HTML document to include an onload attribute on the body element that will add an event listener for this event as soon as the body content has loaded. However, this can occur at any time, before or after the DOM is ready. Therefore, if you’re using any of the native functionality of the device, like its accelerometer, for example, it’s advisable for you to put your main block of code into the deviceready
event listener’s callback function, and not use the dojo/domReady!
module. And immediately I’m gonna contradict myself. Read on.
deviceTheme, or: How I Learned to Stop Worrying and Love the DOM
I’m guessing that if you’re looking to use Dojo on mobile, you’d be happy to have some automatically-loaded native-looking themes included! For instance, check out this sample tweet app Dojo showcases. Wouldn’t it be awesome if those styles magically applied themselves to your iPhone or iPad app, and Android styles to your Android app, and so on? Well, Dojo serves this up to you with very little work to be done on your part. All you have to do is load the deviceTheme module and call the parsing function that the dojox/mobile/parser
module provides. It’ll parse your HTML document for views that you have written declaratively into any element attributes. This is all a part of the dojox/mobile
and dojox/deviceTheme
modules and I won’t explain it here — instead, check out how they made the tweet app, Tweetview, for details.
If you want to use the deviceTheme module in your PhoneGap application, I will suggest that you don’t include it in the deviceready
event listener callback as I mentioned above. I tried it, and apps in both Android and iPhone displayed an ugly, unstyled HTML document for a few seconds until deviceTheme kicked in. I was able to work around it by using the dojo/domReady!
module in the <head>
of my document only to start the mobile parser, then loading all my main code from the deviceready
callback. Also, you’re going to want to copy the directory structure for the themes’ css files into your dojo base directory as they were when you downloaded your local copy of dojo. Include only the dojox/mobile/themes
directory into your project — if you used the build script to build your singular js file, you’ll need nothing else.
Misc
- Mixing-and-matching phonegap.js files is not recommended. They’re matched to the specific device platform (iPhone, Android, etc.) you’re working with.
- Debugging on your desktop browser makes things easier.
Best of luck to you on your mobile and other projects! Hopefully your work is now easier.
Comments