building an app to cater for WP7,Iphone & Android - mvvm

I am about to start building an app that will be used across all platforms. I will using monotouch and monodriod so I can keep things in .net
I'm a little lazy so I want to be able to reuse as much code as possible.
Lets say I want to create an application that stores contact information. e.g. Name & Phone number
My application needs to be able to retrieve data from a web service and also store data locally.
The MVVM pattern looks like the way to go but im not sure my approach below is 100% correct
Is this correct?
A project that contains my models
A project that contains my views,local storage methods and also view models which I bind my views to. In this case there would be 3 different projects based on the 3 os's
A data access layer project that is used for binding to services and local data storage
Any suggestions would be great.
Thanks for your time

Not specifically answering your question, but here are some lazy pointers...
you can definitely reuse a lot of code across all 3 platforms (plus MonoWebOS?!)
reusing the code is pretty easy, but you'll need to maintain separate project files for every library on each platform (this can be a chore)
MVVM certainly works for WP7. It's not quite as well catered for in MonoTouch and MonoDroid
some of the main areas you'll need to code separately for each device are:
UI abstractions - each platform has their own idea of "tabs", "lists", "toasts", etc
network operations - the System.Net capabilities are slightly different on each
file IO
multitasking capabilities
device interaction (e.g. location, making calls etc)
interface abstraction and IoC (Ninject?) could help with all of these
The same unit tests should be able to run all 3 platforms?
Update - I can't believe I just stumbled across my own answer... :) In addition to this answer, you might want to look at MonoCross and MvvmCross - and no doubt plenty of other hybrid platforms on the way:
https://github.com/slodge/MvvmCross
http://monocross.net (MVC Rather then Mvvm)

Jonas Follesoe's cross platform development talk: Has to be the most comprehensive resource out there at the moment. He talks about how best to share code and resources, abstract out much of the UI and UX differences, shows viable reusable usage of MVVM across platforms and nice techniques for putting together an almost automated build. (yes, that includes a way for you to compile you monotouch stuff on Visual Studio)
Best of all he has a available source code for the finished product and for a number of the major component individually placed in its own workshop project and a 50 + page pdf detailing the steps to do so.FlightsNorway on github
IMO the only thing missing is how best to handle local data storage across all platforms. In which case I would direct you to Vici Cool Storage an ORM that can work with WP7, MonoTouch and (while not officially supported) MonoDroid.
*Disclaimer* The site documentation isn't the most updated but the source code is available. (Because documentation is Kriptonite to many a programmer)

I think the easiest way to write the code once and have it work on all three platforms will probably be a web-based application. Check out Untappd for example.

You can start by looking at Robert Kozak's MonoTouch MVVM framework. It's just a start though.
MonoTouch MVVM

Related

Consuming ViewModels in MonoDroid / MonoTouch

I've decided to dabble a bit in MonoDroid and MonoTouch and port one of my WP7 apps as a starter. I would really like to reuse my existing ViewModels but since both Android and iOS seem to have no such thing as XAML's strong databinding I would like to ask if anyone went that route before and can recommend some best practices or existing solutions.
We're doing this with an application right now, but writing for iOS first (even before Windows). It is not full of rainbows and ponies for sure.
I would recommend the following:
Use a MVVM framework on Windows that doesn't require you to expose ICommand on every action the user takes (like Caliburn, for example), it also shouldn't require a dependency to it from within all of your ViewModels.
Conditionally inherit the WPF-specific pieces of your ViewModelBase class, you can do this with partial classes or an #if iPhone directive. INotifyPropertyChanged or ICommand are examples.
Use an IoC container, it is very helpful to abstract out things like saving settings to the filesystem which will be very different on all platforms. Also helps to sort out your dependencies as well, which is very helpful for separating out platform-specific code from non-platform specific.
Use a "messenger" of some kind (example here), usually included with an MVVM framework. This is a must in my opinion, at least for iOS. Apple's MVC is so all over the place, it's better to have global messages you can subscribe to in a weak referenced (and decoupled) way.
Use MVC on each platform like you would natively, then treat each ViewModel as you would if you were calling it manually. There are no UI bindings, no ICommand, so keep your ViewModel's simple.
Linking files is the best trick ever. You don't want a copy of each view model per platform, so make sure you know how to link to a file within projects in Visual Studio and MonoDevelop. This also makes #if iPhone and #if Android statements possible.
I know you are working with an existing application, so it's tough. It may be simpler to just reuse your business model and that's it. Android and iOS have MVC patterns of their own, and are drastically different from WPF. You might also only need a subset of each ViewModel on mobile devices, which could make it easier to just rewrite.
In our case:
We're using TinyIoC (also has it's own messenger)
We will use Caliburn-Micro when we start on WPF, we don't need some of the features in full Caliburn
I've recently finished a large project which we wrote wp7 first, and which was then ported into touch and droid.
As part of this we've released our own mvvm framework - including some databinding support for touch and droid - the source is available at http://github.com/slodge/mvvmcross
The experience of porting to droid was good - the axml layout files provided a good hook for databinding. Currently, however, i'm not quite as happy with the binding we achieved for touch - although montouch.dialog does at least provide us with some nice looking code sometimes.

lite app and full app - best practise for dividing?

What is the best practise for developing a lite app and a full app with additional features? It is better to create 2 projects in eclipse oder just one project with e.g a constant for switching the functionality? I think there are advantages and disadvantages for both approaches: With 2 projects you always have to do everything twice if you update your apps, with only one project the app is larger then needed.
I didn't find much about this topic, so I ask you, what is your approach or do you know some articles explaining solutions?
At least, I found this:
http://blog.donnfelker.com/2010/08/05/howto-android-full-and-lite-versions/
Any more approaches/ideas ?
Thanks.
I'm not familiar with the specifics of Android development, but in general I would move all the real code to one or more library projects and then reference that from specific projects that can take a "pick-and-mix" to assemble differently capabable applciations.
Taking that a step further component technologies like OSGi allow you to pull together arbitrary selections of components as specified in a configuration file.

Should I learn how web frameworks work before I use them?

I'm interested in creating a basic web application (for learning, but I want to finish within a few months), and I've read that using a web framework can make that task much easier.
After reading about different frameworks online, it seems to me that using frameworks would hide a lot of detail on they work. I fear that if I use a framework, I won't really know how my website is running.
Is it important to understand how frameworks do what they do, or am I worrying too much? (eg. I don't know how the Linux kernel works, or the C compiler, etc.)
Even if you don't have a particular interest in web frameworks, I would say it's good to play with a few and then crack them open if only for the exposure to new design patterns and solutions that can be applied anywhere in development. (MVC in particular when talking about most web frameworks)
It is (to some extent) important to understand how frameworks work, but you'll never learn that without using them.
So, start using some framework and you'll get basic understanding of it. And then, if you have interest, you can always dig deeper into it (maybe even submit patches and participate in its development). But not in the opposite order.
Using your analogy, you don't become Linux kernel developer without being Linux user for some time.

How to code sharing between Android and iOS

I'm moving away from strict Android development and wanting to create iPhone applications. My understanding is that I can code the backend of iOS applications in C/C++ and also that I can use the NDK to include C/C++ code in Android apps. My question however is how? I've googled quite a bit and I can't find any clear and concise answers.
When looking at sample code for the NDK, it seems that all the function names etc. are Android (or at least Java) specific and so I would not be able to use this C/C++ backend to develop an iPhone frontend?
I'd appreciate some clarification on this issue and if at all available some code to help me out? (even just a simple Hello World that reads a string from a C/C++ file and displays it in an iOS and Android app).
Thanks guys
Chris
Note that I almost exclusively work on "business/utility/productivity" applications; things that rely heavily on fairly standard UI elements and expect to integrate well with their platform. This answer reflects that. See Mitch Lindgren's comment to Shaggy Frog's answer for good comments for game developers, who have a completely different situation.
I believe #Shaggy Frog is incorrect here. If you have effective, tested code in C++, there is no reason not to share it between Android and iPhone, and I've worked on projects that do just that and it can be very successful. There are dangers that should be avoided, however.
Most critically, be careful of "lowest common denominator." Self-contained, algorithmic code, shares very well. Complex frameworks that manage threads, talk on the network, or otherwise interact with the OS are more challenging to do in a way that doesn't force you to break the paradigms of the platform and shoot for the LCD that works equally badly on all platforms. In particular, I recommend writing your networking code using the platform's frameworks. This often requires a "sandwich" approach where the top layer is platform-specific and the very bottom layer is platform-specific, and the middle is portable. This is a very good thing if designed carefully.
Thread management and timers should also be done using the platform's frameworks. In particular, Java uses threads heavily, while iOS typically relies on its runloop to avoid threads. When iOS does use threads, GCD is strongly preferred. Again, the solution here is to isolate the truly portable algorithms, and let platform-specific code manage how it gets called.
If you have a complex, existing framework that is heavily threaded and has a lot of network or UI code spread throughout it, then sharing it may be difficult, but my recommendation still would be to look for ways to refactor it rather than rewrite it.
As an iOS and Mac developer who works extensively with cross-platform code shared on Linux, Windows and Android, I can say that Android is by far the most annoying of the platforms to share with (Windows used to hold this distinction, but Android blew it away). Android has had the most cases where it is not wise to share code. But there are still many opportunities for code reuse and they should be pursued.
While the sentiment is sound (you are following the policy of Don't Repeat Yourself), it's only pragmatic if what you can share that code in an efficient manner. In this case, it's not really possible to have a "write once" approach to cross-platform development where the code for two platforms needs to be written in different languages (C/C++/Obj-C on iPhone, Java for Android).
You'll be better off writing two different codebases in this case (in two different languages). Word of advice: don't write your Java code like it's C++, or your C++ code like it's Java. I worked at a company a number of years ago who had a product they "ported" from Java to C++, and they didn't write the C++ code like it was C++, and it caused all sorts of problems, not to mention being hard to read.
Writing a shared code base is really practical in this situation. There is some overhead to setting up and keeping it organized, but the major benefits are these 1) reduce the amount of code by sharing common functionality 2) Sharing bug fixes to the common code base. I'm currently aware of two routes that I'm considering for a project - use the native c/c++ (gains in speed at the expense of losing garbage collection and setting targets per processor) or use monodroid/monotouch which provide c# bindings for each os's platform functionality (I'm uncertain of how mature this is.)
If I was writing a game using 3d I'd definitely use approach #1.
I posted this same answer to a similar question but I think it's relevant so...
I use BatteryTech for my platform-abstraction stuff and my project structure looks like this:
On my PC:
gamename - contains just the common code
gamename-android - holds mostly BatteryTech's android-specific code and Android config, builders point to gamename project for common code
gamename-win32 - Just for building out to Windows, uses code from gamename project
On my Mac:
gamename - contains just the common code
gamename-ios - The iPhone/iPad build, imports common code
gamename-osx - The OSX native build. imports common code.
And I use SVN to share between my PC and Mac. My only real problems are when I add classes to the common codebase in Windows and then update on the mac to pull them down from SVN. XCode doesn't have a way to automatically add them to the project without scripts, so I have to pull them in manually each time, which is a pain but isn't the end of the world.
All of this stuff comes with BatteryTech so it's easy to figure out once you get it.
Besides using C/C++ share so lib.
If to develop cross-platform apps like game, suggest use mono-based framework like Unity3D.
Else if to develop business apps which require native UI and want to share business logic code cross mobile platforms, I suggest use Lua embedded engine as client business logic center.
The client UI is still native and get best UI performance. i.e Java on Android and ObjectC on iOS etc.
The logic is shared with same Lua scripts for all platform.
So the Lua layer is similar as client services (compare to server side services).
-- Anderson Mao, 2013-03-28
Though I don't use these myself as most of the stuff I write won't port well, I would recommend using something like Appcelerator or Red Foundry to build basic applications that can then be created natively on either platform. In these cases, you're not writing objective-c or java, you use some kind of intermediary. Note that if you move outside the box they've confined you to, you'll need to write your own code closer to the metal.

Shared Library for iPhone and BlackBerry

I have a set of functionality (classes) that I would like to share with an application I'm building for the iPhone and for the Blackberry (Java). Does anyone have any best practices on doing this?
This is not going to be possible as far as I understand your question - the binary format for the iPhone and Java are not compatible - and even for a native library on a blackberry device.
This is not like building for OS X where you can use Java unfornately the iPhone doesn't support Java.
The best idea is probably to build you library in Objective-C and then port it to Java which is an easier transition than going the other way. If you programme for Objective-C and make sure you code has no memory leaks - then the changes are not so complex.
If you keep the structure of your classes the same then you should find maintenance much simpler - fix a bug in the Java and you should find it easy to check for the same bug in the ObjC methods etc.
Hope this helps - sorry that it is not all good news.
As Grouchal mentioned - you are not going to be able to share any physical components of your application between the two platforms. However you should be able to share the logical design of your application if you carefully separate it into highly decoupled layers. This is still a big win because the logical application design probably accounts for a large part of your development effort.
You could aim to wrap the sections of the platform specific APIs (iPhone SDK etc.) that you use with your own interfaces. In doing so you are effectively hiding the platform specific libraries and making your design and code easier to manage when dealing with differences in the platforms.
With this in place you can write your core application code so that it appears very similar on either platform - even though they are written in different languages. I find Java and Objective-C to be very similar conceptually (at least at the level at which I use it) and would expect to be able to achieve parity with at least the following:
An almost identical set of Java and Objective-C classes with the same names and responsibilities
Java/Objective-C classes with similarly named methods
Java/Objective-C methods with the same responsibilities and logical implementations
This alone will make the application easier to understand across platforms. Of course the code will always look very different at the edges - i.e when you start dealing with the view, threading, networking etc. However, these concerns will be handled by your API wrappers which once developed should have fairly static interfaces.
You might also stand to benefit if you later developer further applications that need to be delivered to both platforms as you might find that you can reuse or extend your API wrappers.
If you are writing a client-server type application you should also try and keep as much logic on your server as possible. Keep the amount of extra business logic on the device to a minimum. The more you can just treat the device as a view layer the less porting you'll have to do over all.
Aside from that, following the same naming conventions and package structure across all the projects helps greatly, especially for your framework code.
The UI API's and usability paradigms for BlackBerry and iPhone are so different that it won't be possible in most cases to directly port this kind of logic between apps. The biggest mistake one could make (in my opinion) is to try and transplant a user experience designed for one mobile platform on to another. The way people interact with BlackBerrys vs iPhones is very different so be prepared to revamp your user experience for each mobile platform you want to deploy on.
Hope this is helpful.
It is possible to write C++ code that works in both a BB10 Native app and an iOS app.
XCode would need to see the C++ files as ObjectiveCPP code.
I am currently working on such a task in my spare time. I have not yet completed it enough to either show or know if it is truly possible, but I haven't run in to any road-blocks yet.
You will need to be disciplined to write good cross-platform code designed w/ abstractions for platform-specific features.
My general pattern is that I have "class Foo" to do cross platform stuff, and a "class FooPlatform" to do platform specific stuff.
Class "Foo" can call class "FooPlatform" which abstracts out anything platform specific.
The raw cross-platform code is itself not compile-able on its own.
Separate BB10 and XCode projects are created in their respective IDEs.
Each project implements a thin (few [dozen] line) "class FooPlatform" and references the raw cross-platform code.
When I get something working that I can show I will post again here...