Something that drives me crazy with software companies is that they do not properly handle cross-platform development from what I've seen. While at Microsoft's TechED North America Conference back in June this year, I spoke with several developers who were basically starting from scratch or doing some sort of convoluted way of putting some code in a DLL and then referencing it for each platform. Done right, you can create iOS (iPad/iPhone), Android and Windows Phone 7.x applications with the only platform specific code being taking the data and binding it to each platforms UI.

My approach is to leave the data and business logic where it should be (in your data center/cloud) and leave the presentation and interaction to the device (iPhone, iPad, Droid, Windows Phone etc). To me, every developer should be applying this ideal. Platforms are coming and going so fast, wouldn't it suck if you just spent all of this time programming in a platform specific language (like Objective-C on iOS) only to find out from your CEO that he or she promised a port of your application or game to Platform XYZ in a month.

Having a true 3 tier architecture like in any software development should be embraced even if there is added startup time to get that first pixel displayed on your client device.

My Spring 2012 developed Mobile architecture consists of:
-SQL Server 2008 R2 Database
-SQL Stored Procedures for nearly all I/O to the WCF Service
-Serialized Struct Containers for database/business objects
-Task Parallel Library usage for all conversions to and from the Serialized Structs to the SQL Stored Procedures
-Operation Contracts for all I/O (ie Authentication, Dropdown Box objects etc)

For example, assume you had a Help Ticket System in your Mobile Application. A Help Ticket typically has several 1 to many relationship Tables associated with it. For instance you could have a history with comments, status changes, multiple files attached etc. Pulling all of this information across a web service in multiple calls is costly especially with the latency involved with 3G and 4G connections. It is much more efficient to do one bigger call, thus doing something like this is the best route I found:

[Serializable] public struct HT_BASE_ITEM {
     public string Description; public string BodyContent; public int CreatedByUserID; public int TicketID; public List<HT_COMMENT_ITEM> Comments; public RETURN_STATUS returnStatus; }
public HT_BASE_ITEM getHelpTicket(int HelpTicketID) {
     using (SomeModel eFactory = new SomeModel()) {
     HT_BASE_ITEM htBaseItem = new HT_BASE_ITEM(); getHelpTicketSP_Result dbResult = eFactory.getHelpTicketSP(HelpTicketID).FirstOrDefault(); if (dbResult == null) {
     htBaseItem.returnStatus = RETURN_STATUS.NullResult; return htBaseItem; }
htBaseItem.Description = dbResult.Description; // Setting the rest of the Struct's properties here return htBaseItem; }
public RETURN_STATUS addHelpTicket(HT_BASE_ITEM newHelpTicket) {
     using (SomeModel eFactory = new SomeModel()) {
     HelpTicket helpTicket = eFactory.HelpTicket.CreateObject(); helpTicket.Description = newHelpTicket.Description; // Setting the rest of the HelpTicket Table's columns here eFactory.HelpTicket.AddObject(helpTicket); eFactory.SaveChanges(); // Error handling here otherwise return Success back to the client return RETURN_STATUS.SUCCESS; }
As you can see, the input and output are very clean, if more functionality is desired, i.e. a new field to capture, update the Struct & the input/output functions in the WCF Service, update the WCF reference in your device(s) and add the field to your UI to each device. Very quick and easy in my opinion.

I've gotten in the habit of adding an Enum property to my returned object depending on the possibility of possibly returning Null or some other problem during the data grabbing or setting operations in my WCF Services. It makes tracking down bugs a lot easier and often if an error occurs I simply record it to a SQL Table and add a front end inside the main ASP.NET Web Application with the logged in user, version of the client app, version of the wcf service (captured via AssemblyInfo). Endusers aren't the most reliable to report issues, so being proactive especially in the mobile realm is key from what I've found.

This approach does take some additional time upfront, but I was able to create a 100% feature to feature port to Windows Phone from iOS in 3 days for a fairly complex application because I only had to worry about creating a good looking UI in XAML and hooking up my new UI to those previously existing Operation Contracts in my WCF Service.

This architecture probably won't work for everyone, but I took it a step further for a recent enterprise application where there were several ASP.NET, WinForm and Classic SOAP Services on various .NET versions. An easy solution would have been to simply create a common DLL with the commonly used functionality and reference that in the other platforms. The problem with that being, a fix would need to be deployed to all of the clients and I haven't yet tried a .NET 4.5 Class Library in a 1.1 ASP.NET solution though I can't imagine that would work too well if at all. Creating all of the functionality in a WCF Service and having the clients consume this service has been a breeze. One fix in the WCF Service generally fixes all of the platforms, which is great. Those looking to centralize business logic and database access should really look to this approach.