One of my current projects at Jam Warehouse is to port the app, You & Your Puppy, from the iPhone/iPad to the Android devices (Smart-phones/Tablets). Over the month of November, I have completed the first version and is now undergoing review at our client, DogsTrust.
It is my first ever Android app as well as my first ever mobile application. The current version that is being tested is written in Java. It is also my first Java application as well. (Lots of firsts 🙂 I then re-created the app using MonoDroid using C# – this is still only been tested in the emulator as I haven’t bought the MonoDroid licence yet. I am currently porting the app to the Windows Phone as well. I opted to use the MonoDroid/MonoTouch instead of native languages for several reasons:
- I am a total .NET addict – as you can see by the title of this blog 🙂
- Code re-usability – Write once, test once, deploy n times, get n money!
- Automatic memory management – who wants to dispose objects manually anyway?
- Make use of advanced C# features and short-cuts – I can churn out some serious code…
- And who wants to learn Objective-C or use Eclipse – C# and Visual Studio for me!
Code re-usability is really cool if you are having to write apps for 4 or more different platforms:
- Java for Android
- Objective-C for iPhone
- C# for Windows Phone
- Java for Blackberry
- HTML 5 for everything else
We could just use PhoneGap
or something similar for all the devices, but why make it too easy? Lets go native! C# for Android/iPhone/Windows Phone and HTML5 for all the other players in the game 🙂
We all know (or at least I hope we do) that the iPhone has a “slightly” different layout to the Android phone. So, how do I get this “write once” thing in the list? Well, I didn’t tell the whole story as you can’t really 🙂
I do have an element of “write once”, but not for the entire app, just the non-visual part. As all the versions are going to be reading from a database and showing images/videos, we can use the same code for this part.
But there’s a catch, as always, what database do we use? We can use xml files for the data, but who wants to? We are advanced guys here, we use a database when a database is “needed”, just now we have to expand this app. As the original database was a SQLite
one, so I used that. No complaints there as it is one of the best (if not the best) for mobile development. But now there’s another catch – this time with Microsoft: Windows Phones don’t have SQLite. And you can’t put the C++ version on the device either. So what do we do? Do we use a different database especially for this? No! we use the C# version called System.Data.Sqlite
– much easier than maintaining two databases 🙂 – Don’t we all love this thing called C#?
OK, so we have the database. Now we need to read this data. We can of course write SQL queries and use the SqliteCommand classes, but who wants to use strings in a strongly typed language? Not me. After a little bit of research a found SQLite-NET
a very small ORM for the iPhone. I was saved from strings! It also works on the Android phones! But maybe you noticed that I didn’t say anything about the Windows Phone, That’s right it doesn’t work! – Yup, Microsoft is making things hard for me, but I will not yield, not even to the global monopolistic software company that churns in the billions hourly! No! I re-write the SQLite-NET library (or just tweak it slightly). SQLite-NET was originally using the [DllImport] attributes (P/Invoke) to gain access to the sqlite3.dll that is stored somewhere on the filing system on each device. But for those who don’t know, no P/Invoke on the Windows Phone.
I converted the ORM to use the native SqliteCommand and SqliteConnection instead of the P/Invokes. I don’t actually know why the guys recreated those two classes when they could have just used them instead. Maybe there’s something I don’t know 🙂 I practically halved the code and reduced the amount of possible bugs.
So, now we are up and running with the database, a strongly typed ORM and I can use LINQ to SQLite as well!
Now we get to the basic functionality of the app, showing the information to the user! This is where the not-so-well-documented MonoCross
library comes into play. (I’m hoping to buy this book Professional Cross-Platform Mobile Development in C#
that’s supposed to show me the best way to use the framework). All the navigation between screens is taken care of and all getting the data ready for showing is done. Now, the user wants to click (or touch) on something, that’s why they bought the app in the first place :). Here’s the “snag”. We want cross-platform, but we also want the app to look like it was especially designed for each device – although it wasn’t. So we recreate each GUI screen for each platform, but we don’t use any non-platform specific code and if we have to, we abstract it!
In order to get the UI updates and things to happen, I subscribe to events that are raised on the Model, and then perform the necessary tasks to show each page to the user. I also catch all the events from the UI and perform the respective actions on the Model. For example, when the user clicks a link/button the command is sent to my middle-ground library. This library checks to see if the command is a navigation command. If it is, it then notifies the MonoCross framework that we want to navigate to wherever. If it is an action command, we inform the Model of the action we want to perform. The model is then updated, and the Model then fires an event that the UI will know that it has to change.
When we navigate, each screen has an abstracted helper class that receives the command as a parameter, which is then processed and used to inform the Model of the actions required (if any). When the actions are finished, the new screen is displayed.
Here is a basic diagram of the flow of the app from the time the user presses start and just how little code is actually needed for the platform specific areas.
|As this diagram shows, most of the code is re-used.
And to prove it (mostly to myself), I was able to port the basic functionality of the Android version of the app to the Windows Phone in about 2-3 hours. There was almost no need for changes to the shared code. A bit of tweaking did improve it, but all the platforms – and future ones – will benefit.