Sunday, November 18, 2012

MOBILE DEVELOPMENT DAY TWO:
Hours' worth of hidden gotchas and forgotten details


My previous posts about making mobile apps with Phonegap/Cordova, ended with launching the simulators and running the sample app. Today's project was to get a have the page load to a simple Leaflet map centered on my location. This is about the simplest non-trivial app possible, but it took me about 4 hours because of the hidden gotchas.

So, here are a few of the snags I hit upon. If even one of them saves you even a half-hour of puzzling, you're welcome. :)


ANDROID: PHONEGAP FAILS TO CREATE ASSETS/WWW

After my first draft, I threw out my project folder and used ./create to make a new one as before.
 This new one lacked the assets/www folder and its behavior was "Hello World, YourAppNameHere!" Creating a new www folder, and copying the content of the demo app out of Phonegap's folder, didn't change anything. I even went as far as destroying the project folder, using ./create again, and getting the same result: no www, and creating one doesn't help.

The solution was to move Phonegap out of C:\Program Files where I had it. It is now C:\Users\Gregor\phonegap-2.2.0 and it creates new projects perfectly, even with their www content.

I don't know what was going wrong, as I'm an admin account, and copying files out of C:\Program Files shouldn't have been an issue.. But short version: My previous advice about using C:\Program Files may not work as well as I had thought, after a few more creations.


ANDROID: PUTTING THE APP ONTO A REAL PHONE

To deploy an app onto your phone, you will need the Google USB Driver. This allows communication between the Android SDK and the phone's innards. This is not the same as using your phone as a Disk Drive or USB Storage device.
  • Go into the Start menu, type "android" You should see android.bat as an option. Click it.
  • This opens the Android SDK Manager. Scroll down to Extras and make sure that Google USB Driver is listed as Installed. If it is not, check it, click Install 1 Package, and then close the SDK Manager.
The SDK Manager doesn't install the driver at all, but merely downloads the driver INF files. You still need to install them, and that process varies by your operating system. Fortunately there is a decent writeup about this already:
    http://developer.android.com/tools/extras/oem-usb.html#InstallingDriver

On my device (an HTC Incredible, which was hot stuff in 2010) the Google and OEM drivers do not work. For the HTC Incredible, I used HTC Sync from HTC's website. Despite its name, it also involves that special USB driver.

Once these two surprises were taken care of, I can now deploy my Leaflet app to my old phone, and it works A-OK.



IOS:APP SIGNING & PROVISIONING

When I tried to run my app on the borrowed iPad, it wouldn't build: The profile doesn't have a valid key for signing the app. Evidently deploying your own app onto your own iPad, you still need Apple's permission. And getting it was a half hour of looking up documentation about "provisioning profiles" so I could get permission to develop on my own iPad.

* Connect your iPad to your Mac. In XCode, look in the upper-right to find the Organizer, and look in the Devices section. You should see your iPad listed, including an Identifier, a Provisioning section, and a list of Applications which you have installed onto it.
* Do a Google search for "ios provisioning portal" and follow the link, logging in to the iOS Dev Center. Presumably you already have an account here if you signed up for a developer license.
* After you log in, follow the link for iOS Provisioning Portal, then use the Development Provisioning Assistant. This is a somewhat lengthy wizard, which will walk you through several steps.

Eventually, you will have imported your new identity into XCode and will have tagged your iPad with an identity as well, and Apple and XCode will allow you the privilege of installing programs onto your own hardware. (and folks gripe that Microsoft is invasive and controlling?)


ANDROID AND iOS CORDOVA.JS ARE DIFFERENT

This one caught me by surprise: I got my app loaded onto my iPad, but it wouldn't run. If I put alert() statements into index.js they would execute, but the deviceready event would never happen.

Turns out, cordova-2.2.0.js is not the same between platforms. The first 100 lines or so are the same (which is what threw me) but it's definitely the case that they are different later on.

In my case, I have the one codebase stored on a network drive, and I don't want to copy each file over before each editing session. My solution is as follows:
  • I copied in both versions of the cordova.js, naming them IOS-cordova-2.2.0.js and ANDROID-cordova-2.2.0.js
  • In index.html I have <script> tags for both versions, and one is commented out.
  • When I want to compile or test on a platform, I comment and uncomment the appropriate <script> tag.


IOS: NETWORK WHITELISTING

The app was now almost running: it starts, and up comes Leaflet, but no tiles! Fortunately, XCode finally came through and gave me something to go on: "whitelist failed for http://a.tiles.mapbox.com/..."

A straightforward problem: iOS requires a whitelist if they're to make network access (Android does not). This is in the project's Cordova.plist file. Look for the ExternalHosts setting, and simple add an entry for * (yes, a single asterisk as a host name)

This will enable all hosts, and now my Leaflet app works.


It's up to you if you would rather list individual hosts. Personally I find that an unnecessary nuisance, since I'm the author of the app and I doubt that it could be tricked or hijacked to access other sites.



SUCCESS!

After learning and solving these hurdles (getting Apple's permission, finding HTC's special USB drivers, reinstalling Phonegap, and more) everything is working: One tap and I have a Leaflet map centered on my location.

Next steps: make this app something worthwhile...

Monday, November 12, 2012

Mobile Development with Phonegap / Cordova

Part 1 (again): Getting set up for iOS development on OSX


Last week I got my development environment set up for Android: Windows 7, Eclipse, and Phonegap/Cordova. I also got my iBook and set up Xcode, and got the demo app running on iOS. And here's the writeup.

Some if it may be a bit brief, as  I'm presuming you read my writeup about Android, where I describe some synonyms and terminology.




THE STACK

The way to use Cordova (aka Phonegap) to build iOS apps, is to use Xcode on a Mac. The basic stack is:

- A Mac. It must be running Mountain Lion (OSX 10.8) or later.
- An Apple ID so you can use the App Store
- Xcode 4.x
- Phonegap and its create script
- Your iOS device, or the built-in simulator

In fact, it is a violation of the iOS Terms Of Use, to develop an app for iOS not using Apple hardware and authorized tools. So this stack really is it. (comments about Microsoft and the anti-competition lawsuits of the late 1990s, tastefully deleted)

In my case, I hit up eBay and found a used iBook running Mountain Lion for $400.



GETTING AN APPLE ID AND IOS DEVELOPER LICENSE

If you want to deploy your mobile app via the App Store, you will need to extend your Apple ID with an iOS Developer License. This means visiting Apple's website (https://developer.apple.com/programs/ios/) and spending a half hour or so entering your information a few times. It also means spending $99 for a one-year registration as a Bona Fide Developer. (must fight... must not make... snarky comment)

This step is optional, required only once you're past the testing phase and want your app to be available to others.



INSTALLING XCODE

Fire up your Mac, open the App Store, so a search for Xcode. It comes right up, and a few clicks later it's downloading and installing. It's really that painless.

This is a 1.6 GB download, so on household DSL it took overnight. On a cable modem, you'll still have time to catch dinner and a couple episodes of Futurama...

After it's set up, start Xcode and then install the Xcode command-line tools: Preferences / Downloads / Components As long as I was there, I also had it grab a bunch more documentation and libraries. The whole shebang was another 1.1 GB, but again went painlessly.





INSTALLING PHONEGAP (CORDOVA)

Do a Google search for "phonegap download" and download the Cordova library. The version 2.2.0 is about 26 MB, and downloads in a few moments.

The Phonegap library doesn't really "install" but you extract it someplace. On my Mac (Mountain Lion, Safari, very default configuration) the Cordova library unzipped, leaving me a folder. I simply moved the folder into my Documents folder, and renamed it to phonegap



SET UP A PROJECT

Open up a Terminal (use the Spotlight, the magnifying glass, and type "terminal". The icon is a black square) and run these commands:
  • ./Documents/phonegap/lib/ios/bin/create FOLDER_PATH PACKAGENAME PROJECTNAME
  • Close the terminal
 FOLDER_PATH - This is the path to the intended folder for your new project, e.g. ./Documents/MobileApps/WalkTracker
PACKAGENAME - A dotted-format app name combined with domain name, e.g. org.greeninfo.walktracker
PROJECTNAME - The name of your app as you want it to appear, e.g. "Walk Tracker Calorie Counter"
Example (don't forget those quotes!):
./Documents/phonegap/lib/ios/bin/create./Documents/MobileApps/"Walk Tracker" org.greeninfo.walktracker "Walk Tracker Calorie Counter"
This will create a new folder, containing an Xcode project file.



RUN IT!

Open up Xcode and load that project file (or, simply open the project file).

In the upper-left is the familiar arrow button indicating Play. Pick your iOS simulator version, click the button, and there's your demo app.


CONCLUSION

Unlike Windows / Eclipse / Android setup, this one was a snap. Most of my time wasn't spent researching errors, but periodically checking a download bar. The create script ran without issues, and aside from download time I had the demo app running in 10 minutes.

The official version of this setup process is at Phonegap's own website. It's actually really accurate, and I admit that I had little to add except for narrative. (that's a compliment, Phonegap developers)

http://docs.phonegap.com/en/2.2.0/guide_getting-started_ios_index.md.html#Getting%20Started%20with%20iOS


NEXT STEPS

My goal for today (a break, on account of Veterans' Day) is to sit and play with both platforms and get a basic mobile app running. I have only vague ideas as to what it will do, but that's not the important part just yet. :)


Thursday, November 8, 2012

Mobile Development with Phonegap / Cordova

Part 1: Getting set up for Android development on Windows 7

I got a new computer, which freed up my old one for dedicated use as a mobile development platform. My intended approach is to use Phonegap, so I can continue writing in HTML/CSS/JavaScript as I've been doing for 16 years. (then determine whether this method has problems such as slow speed, large app size, etc)

I run Windows and have an Android phone, so this first writeup is about those environments. A future writeup will cover Mac OSX, iOS, and xcode.

THE BASIC IDEA

The basic idea of Phonegap (sorry, I mean Cordova; they changed their name in 2012), is that you create a project folder which contains your HTML, CSS, and JavaScript assets, as well as the Phonegap library. Phonegap effectively acts as a web browser (but it's not), executing the JavaScript and rendering the HTML/CSS, and it brings some non-standard JavaScript features such as cross-domain loading, access to local files, and APIs to the phone's hardware.

Long story short: You start with a project folder, punch in HTML/CSS/JS, and export the whole shebang as an APK.

There are five basic parts to getting started with Phonegap:
* Java Development Kit (JDK), since Phonegap is Java
* Android SDK, since you're writing for Android
* Apache Ant, a build tool for Java apps
* The Cordova library itself, of course
* Eclipse SDK, the all-purpose editor to tie it all together

INSTALLING PREREQUISITES

Do a Google search for "jdk download", find Oracle, download the JDK 7 package, run the installer and click through the menus. Make a note of the directory (something like C:\Program Files\Java\jdk1.7) because you will need it later.

Do a Google search for "android sdk download", download the SDK installer, run it. I prefer to have it directly in my folder C:\Users\Gregor\AndroidSDK so it's easier to find and remember. Note that the SDK will later want to download files and create subfolders, so it should be in your documents and not someplace system-wide such as C:\Program Files. Wherever you install it, keep a note of the folder location because you will need it later.

Do a Google Search for "apache ant binary" and download a binary package. There is no installer, simply unzip it someplace. I put it under C:\Program Files\Apache Ant but had to provide admin privilege. Make a note of this directory, because you will need it later.

All three of these packages will involve some command-line usage later, so we have to set some environment variables.
  • Go into your Start menu, type "environment" and select "Edit environment variables for your account"
  • You'll get a panel listing a few variables such as TEMP, and some self-explanatory buttons such as New and Edit.
  • Set JAVA_HOME to the installation directory for the JDK, e.g. C:\Program Files\Java\jdk1.7
  • Set the PATH to include the JDK's bin directory, e.g. C:\Program Files\Java\jdk1.7\bin
  • Set the PATH to include the Android SDK's tools subdirectory, e.g. C:\Users\Gregor\AndroidSDK\tools
  • Set the PATH to include Apache Ant's bin subdirectory, e.g. C:\Program Files\Apache Ant\bin
Note that the syntax of a PATH is to join together multiple directory names with a semicolon ; character, like this:
C:\Program Files\Java\jdk1.7\bin;C:\Users\Gregor\AndroidSDK\tools;C:\Program Files\Apache Ant\bin
If you already had a PATH set, simply add a ; to the end of it, then add these three new ones.
Now test it by opening a command prompt (if you had one open already, close it and open a new one). Run the following commands and check the output:
# This should display the path of the JDK
echo %JAVA_HOME%

# This should run the Java compiler, which will show some usage help
"%JAVA_HOME%"\bin\javac

# This should run Ant, which will complain that build.xml doesn't exist
ant

# This should launch the Android SDK manager. just close it
android.bat

SETTING UP ECLIPSE & ANDROID

We're not finished yet!

Now Google and download Eclipse SDK (also called Eclipse Classic) and unpack it someplace. There is no installer, just unpack it someplace convenient. I like to put it in C:\Program Files\Eclipse and then drag it into my Start menu.

Now start Eclipse and install the Android Development Tools (ADT) plugin, which allows Eclipse to access the Android SDK.
  • Start Eclipse
  • Go into Help / Add New Software
  • Add a new repository. name it "ADT Plugin" and use the URL https://dl-ssl.google.com/android/eclipse/
  • It will show you a list of default packages which it will download. Click OK and let it download for a little while...
  • When Eclipse restarts, you should be prompted by ADT asking where to find the Android SDK. Tell it to Use Existing SDKs, and then show it where you installed Android SDK.
I prefer to test my future apps on an Android emulator, so I can test multiple OS versions and not risk my phone while I tinker. As such, I will take an extra step here to install several more packages:
  • Open Windows / Android SDK Manager, Look over the list of packages. For various versions of Android OS, the SDK platform and also the Intel x86 Atom System Image. You will need these for the versions of Android OS you want to support.
  • Install the Extras / Intel x86 Emulator Accelerator (HAXM). This enables the Android Virtual Device (AVD) to run much faster than it would without.
  • Click OK, Accept, and wait a while...
If you installed the HAXM, you will need to run an installer too; the SDK Manager downloaded but didn't really install it. Go into your Android SDK folder (C:\Users\Gregor\AndroidSDK\tools), go into Extras / Intel and look for the IntelHaxm.exe setup file. It's a standard wizard: double click, Next, Finish.

Now you're finally done setting up! It's time to make a project!


FINALLY, START A PROJECT!

Download the Phonegap / Cordova package from http://phonegap.com/download It is not an installer, just a ZIP file. Unpack it someplace convenient like C:\Program Files\Phonegap\Cordova 2.2.0

The Cordova distribution supports several different target platforms, all under the lib folder. Naturally, we want to use "lib/android"

To start a new project, use the command-line "create" script. This will create a folder containing various bootstrap elements for your new app: a copy of the Phonegap library, a folder for WWW assets with JS, CSS, and HTML subfolders, and so on.
  • Open a command prompt
  • Type: C:\Program Files\Phonegap\Cordova 2.2.0\lib\Android\bin\create FOLDER_PATH PACKAGENAME PROJECTNAME
  • Exit the command prompt
 FOLDER_PATH - This is the path to the intended folder for your new project, e.g. C:\Users\Gregor\Mobile\Demo Project
PACKAGENAME - A dotted-format app name combined with domain name, e.g. org.greeninfo.demoproject1
PROJECTNAME - The name of your app as you want it to appear, e.g. "Demonstration Project"
Example (don't forget those quotes!):
C:\Program Files\Phonegap\Cordova 2.2.0\lib\Android\bin\create C:\Users\Gregor\Mobile\"Demo Project" org.greeninfo.demoproject1 "Demonstration Project"
Start up Eclipse. Go into File / New / Project, and a wizard will allow you to pick from a set of project templates. Select Android Project From Existing Code, then lead it to the project folder you just created.

You now have an Android project underway! The left-hand panel shows the files in your project (Package Explorer). The right-hand panel will show your program code.

TEST IT RIGHT AWAY

If you're like me, you'll immediately want to make test their own demo. (don't you hate it when someone's own Hello World doesn't work?)

In the Package Explorer (the left-hand side), scroll to the top and right-click on the root object, which is your project. Select Run As / Android Application.

There are three possible things that may happen here:
  1. If your phone is attached and USB Debugging is enabled, or if you have previously created an Android Virtual Device (AVD) , you will be presented with a list of target devices. Pick the one you want to use.
  2. If there is only one Android device (phone or AVD), it will be chosen automatically without prompting you.
  3. If there are no Android devices available (no phones, no AVDs) then you will need to create one or attach one. This is a few New buttons, and selecting your choice of Android OS version (aka SDK level) and amount of virtual storage. It then lets you choose which one to use, or uses the only one.
Now the Android emulator will fire up. Like your real phone, it will take a brief slice of eternity. Eventually you'll unlock the "phone" and browse through the apps. Hey, there it is! Tap it and it works!



Note: I did get an error INSTALL_FAILED_OLDER_SDK and needed to make an adjustment to the Manifest file. See below.

SUCCESS! AND NEXT STEPS...

So far, so good. It was a long and tortuous road, but our environment is set up. For future projects, we just need to run "create" to bootstrap a folder, then open up Eclipse and Run As to test it.

The immediate next step will be development of the app, and this largely means editing HTML, CSS, and JavaScript in the assets folder. Eclipse has the build tools, but for the editing I may fall back to my trusted Komodo Edit.

A followup article will cover the development of my own Hello World app, packaging and permissions via the Manifest file, and actual deployment of a distributable APK file.


FOLLOWUP NOTES: ANDROID OS VERSION, aka SDK LEVEL

A note on terminology: Each version of the Android OS is also referred to as a SDK Level. Android 4.1 Jelly Bean is SDK Level 16. 4.0 Ice Cream Sandwich is SDK Level 15.

The Phonegap starter app probably didn't run when the emulator came up, giving an error of This means that your Manifest file (metadata and configuration about the app, device suport, etc) indicates that the app is for a different version of Android OS.

Check the AndroidManifest.xml file, down at the bottom look for android:minSdkVersion and android:targetSdkVersion In my case, the targetSdkVersion was __VERSION__ instead of a proper number. Setting this to a real number (16 for Jelly Bean) fixed it.

FOLLOWUP NOTES: TIPS AND TROUBLESHOOTING

A note about the Android SDK installation directory. I lied: I really put mine into C:\Program Files\Android SDK. This did mean some additional fussing, though: I had to provide admin privilege to install it, then I had to set the ownership of C:\Program Files\Android SDK to myself, and to grant Full Control to myself. If you have multiple accounts on your computer, this solution may not work. Keep in mind that the SDK will try to download and create files and folders here; if it fails when trying to install packages, check the ownership and permissions.

I chose to install Apache Ant and Cordova to C:\Program Files since it's a convenient place to keep them from cluttering up my documents or my desktop. I did need to provide admin privilege to put the folder there, but it works just fine after that because (unlike Android SDK) these won't make changes later and require special permission.

When running Cordova's "create", it has one very general error message: "missing one of the following". This means that one of those JAVA_HOME or PATH entries is wrong back when you set up JDK, Ant, and Android SDK. Run through those steps again, including the tests.

The Android emulator should be slow but reasonably fast, even on my two-year-old laptop. If it takes more than a few seconds to load, or is really slow, make sure that you have really installed HAXM. Remember, you must download the package via the SDK Manager and then run an installer wizard.

HAXM won't work with some older CPUs, particularly laptop CPUs before 2010. If your CPU is missing the virtualization features, either buy a newer computer or just accept that the emulator will be slow.

If you want to create more Android Virtual Devices (AVDs), e.g. for a new version of Android OS, open Eclipse, go into Window, and select the AVD Manager.