Hello, I am finally joining the party that is the seriesChris Paine and I are writing about developing a mobile app that works with Netweaver Cloud as well as interfaces with an on premise backend (previous posts are here and here. My part in this fun is building the mobile app, and since I'm pro Apple and Chris is pro Android, we decided we had to make it available on both platforms.
Background: Why PhoneGap?
So of course the first conversation we had to have when discussing a mobile app was: native or web app? Having done a pure web app before, I was aware of the benefits, as well as the pitfalls (you can read more about it in my blog post). But before that, we very quickly ruled out the native solution. Why? Because given our expertise in XCode and pure Android development (which I can say for myself was virtually none), it would take far too long. So then we were tossing up between web app or hybrid, and finally settled on hybrid.
Of course if you do your research you will find that many developers out there have gone through the same decision making process, so I won't go into too much detail of the pros and cons of each option. Basically we decided that though a web app would be easier to deploy updates with and be more accessible, we wanted our app to have those pros as well as have some of the pros of a native app too. Which is why we decided to go with a hybrid app. There are a few tools out there now, but we chose to go with PhoneGap as it works with jQuery Mobile and I like how it looks. Also, for the life of me I could not get Sencha Touch to install on my MacBook, maybe because it wouldn't work on Mountain Lion. Sencha Architect worked but I needed to pay for it, plus I couldn't work with jQuery Mobile.
PhoneGap: The Fun Parts
Before I let you in on the fun I had, let me just quickly cover the building blocks required to create a PhoneGap app:
- Download and extract PhoneGap
- Download and extract Cordova
- Create a project in the command line for the platform you want
- Open the project file in the relevant environment
- Install relevant plugins in each environment (Android SDK and tools for Eclipse and simulators in XCode)
- Build your HTML file with the required .js and .css files
- Test in simulator
The first thing I discovered was that PhoneGap had significantly changed since it's last release (I used version 2.2.0). In the older version there was a UI friendly way of installing it and creating a project (in either XCode or Eclipse). PhoneGap has documentation to help you through installation though, so it wasn't too bad in the end. The bottom line is you need both XCode and Eclipse Classic if you want to work on iOS and Android platforms. And both tools require project creation through the command line. Luckily for me PhoneGap had this in their documentation so I didn't have to learn any commands!
Basically the way PhoneGap works is it creates a project in the relevant environment that references a Cordova library. This library is platform specific and gives you access to the platform API, and on device features such as the accelorometer, camera, etc. Even though in this development we are not using any of these capabilities, the plan was to be able to do so in the future. The project comes created with a HTML file that will be the basis of your web app that is encapsulated within the device browser (incidentally this is why it's faster than a pure web app). Here's a screenshot of the two environments I had to work in (Eclipse is FAR EASIER, but I refuse to say I'm pro Android yet, sorry Chris).
Now by far the most annoying thing about using PhoneGap is that I had to develop virtually the same thing in two environments. Thank God for the FileMerge tool to compare the two HTML files or I would have gone blind by now. Exacerbating this annoyance is the fact that jQuery Mobile has little quirks that happen in iOS and not in Android, so the two files couldn't be exactly the same (I used jQuery Mobile version 1.2.0 and jQuery 1.8.0). The two projects also had their own www folders so I had to have duplicates of my .js and .css files (you quickly learn the hard way when something is missing).
HTML5 is awesome
Obviously in the app we chose to use HTML5, largely due to local storage. We wanted our app to appear to behave the same way to the user whether or not it was connected to the server. This meant saving everything onto the device, and refreshing it with server values when it was connected. If you're familiar with HTML already, you won't have any problem at all, as it was a BREEZE compared to some of the other things.
Sorry Android Lovers
The reason I chose to use jQuery Mobile is because I like how it looks. Very Apple like. Unfortunately this meant that Android users would also have that look and feel, and not everyone was that excited about it (that's you Chris). However, to give me some credit, I tried to make the button placements and icons as similar to Android as possible. The bottom line is I still love how Apple apps look
Integration is a dirty word
Most people cringe at this word, but after creating the applications in the relevant environments, it was time to integrate with our server in the cloud (more details in the blog links at the top). The first thing we had to do was register/pair a device with a user. Once a user is logged into our website, they can pair any number of devices, which have their own ID. The idea is to pair the device once, which provides the id and password required to securely connect to the server. Needless to say the id and password is different for every device, but the beauty of this is that all devices for the same user can download the same data.
Having done that, all secure communication with the server is done via ajax calls to RESTful services.Chris came up with the API for all our resource GETs, PUTs, POSTs and DELETEs. All data being received and sent is in JSON format. We had a bit of "fun" using ajax on cross-domain servers (Chris and I will be covering more on that in another blog post). For iOS I had to specify cross-domain = true for every ajax call or it wouldn't work, but it was fine without in Android.
Testing on devices
In this regard, iOS didn't want to play fair. Sure I could test in the simulator just fine, but I wanted to see it work on my own device. With Apple you need to register in the developer program (which costs $99) before you can deploy any application on your device. Android was a dream; you just plug in your device, turn on debugging and deploy it. Also, iOS apps require 1-2 weeks lead time of approval before they publish your app in the App Store, whereas the Google Play Store is much faster. Having said that, testing on the Android simulator was a little bit buggy too, such as the simulator device not connecting to the internet after awhile. I'm pleased to say that the overall look and feel is quite uniform between the platforms. You can see the screenshots below (iOS on left and Android on right)
So here's what I learned during this process:
- Decide on the main purpose of your app, and choose the app type accordingly. If you need to be offline all the time, maybe a native app works better
- Mock up the application in a platform agnostic tool like Balsamic so your design won't be too biased towards any platform
- Choose your target OS level wisely. I picked one that was too high in Android and realised my own device wasn't even there yet. However too low and it won't be compatible with Cordova
- Ensure your HTML and CSS work in both platforms, as sizing of Androids in particular can be very different
- Ensure you have a good web developer tool plugin for your browser. Unless you want to alert everything inside your app, this will prove invaluable for debugging
- Always test in different device rotations (if you don't want them to, lock it). You avoid lots of nasty surprises this way
- To test RESTful calls independently, I recommend the Postman app in Chrome. Helps to determine if your problems are device related
- Finally, Google is your friend. Embrace it warmly
I will be writing another blog with more in depth information about local storage on device and how we sync the data between the device(s) and the server. Stay tuned!!