Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cross-platform Mobile Applications with C# and .NET - Miracle Open World 2012

Cross-platform Mobile Applications with C# and .NET - Miracle Open World 2012

The session will show how you can use C# and .NET to build iOS and Android applications and take full advantage of the APIs provided by the two different platforms. From this, you will find out how to re-use your C# and .NET code across these mobile platforms, including Windows Phone 7 devices and just how much code you can re-use as well as find out how Xamarin are working to make this process as easy as possible.

Chris Hardy

April 24, 2012
Tweet

More Decks by Chris Hardy

Other Decks in Technology

Transcript

  1. Cross-platform Mobile Applications with C# and .NET Miracle Open World

    2012 19th April 2012 There will be QR Codes, be ready!
  2. Chris Hardy • .NET Contractor • Work with Xamarin •

    Wrote some books • First spoke about MonoTouch in January 2010 • http://twitter.com/chrisntr
  3. Agenda • What is Mono? • .NET on iOS with

    MonoTouch • .NET on Android with Mono for Android • Sharing .NET code
  4. What is Mono? • Open source implementation of the .NET

    platform created by Ximian • 2001: Created to bring Windows applications to Linux • 2003: Acquired by Novell with Ximian • Matured at Novell in research mode; now a world-class runtime.
  5. Xamarin • Xamarin founded in May 2011 • Xamarin has

    a perpetual license to all Mono IP: copyrights, patents and trademarks • Focused on mobile app development
  6. What is MonoTouch? • C# on iOS devices (iPhone, iPod

    Touch, iPad) What MonoTouch is not... • Silverlight for iOS devices • Compact Framework for iOS devices • iOS development without a Mac • A meta-platform
  7. What is Mono for Android? • C# on Android devices

    What Mono for Android is not... • Silverlight for Android devices • Compact Framework for Android devices • Supported for Linux • A meta-platform
  8. MonoTouch / Mono for Android Features • MonoDevelop iPhone/Android Add-In

    • Visual Studio support for Android • monotouch.dll / monoandroid.dll • Full static AOT compiler / Allow JIT for Android • Support for all your existing code • Reflection • Generics • LINQ • Anonymous Methods • Lambda’s etc...
  9. MonoTouch APIs .NET APIs Native APIs 3rd Party mscorlib System

    System.Core (LINQ) System.Data Mono.Data.Sqlite System.ServiceModel System.Json System.Web.Services (WCF) System.Xml System.Xml.Linq AddressBook/ AddressBookUI AudioToolbox/ AVFoundation CoreAnimation CoreGraphics CoreLocation EventKit/EventKitUI ExternalAccessory GameKit MapKit NewsstandKit StoreKit Twitter UIKit And so on.... OpenTK OpenGL OpenAL SQLite MonoGame RestSharp Json.NET ServiceStack Steema TeeChart Flurry Analytics RedLaser And so on...
  10. Mono for Android APIs .NET APIs Native APIs 3rd Party

    mscorlib System System.Core (LINQ) System.Data Mono.Data.Sqlite System.ServiceModel System.Json System.Web.Services (WCF) System.Xml System.Xml.Linq Android.Accounts Android.App.* Android.Bluetooth Android.Content.* Android.Database Android.Graphics Android.Hardware Android.Locations Android.Net.* Android.Nfc Android.Text Android.Util Android.Views.* Android.Widget Java.Lang.* Java.Util.* And so on.... OpenTK OpenGL OpenAL SQLite MonoGame RestSharp Json.NET ServiceStack Steema TeeChart And so on...
  11. Win/WP7 WPF Silverlight OSX MonoMac C# Plus ECMA languages .NET

    iOS MonoTouch Android Mono for Android Mono Business Logic and Middleware (engine, core and 3rd party) Native UI APIs Runtime OS Code sharing and native experience
  12. MWC 2012 • 1,635 Lines of shared code - 771

    for ORM • iPhone + iPad (2,476 LOC / 2 Apps) - 57% Re-use
  13. MWC 2012 • 1,635 Lines of shared code - 771

    for ORM • iPhone + iPad (2,476 LOC / 2 Apps) - 57% Re-use • Android (1,095 LOC) - 60% Re-use
  14. MWC 2012 • 1,635 Lines of shared code - 771

    for ORM • iPhone + iPad (2,476 LOC / 2 Apps) - 57% Re-use • Android (1,095 LOC) - 60% Re-use • Windows Phone 7 (896 LOC) - 65% Re-use
  15. Techniques for Cross Platform Code 1. Portable Library Tools 2.

    Linking Files 3. Project Linker 4. Xamarin.Mobile
  16. Portable Library Tools • Pros • One class library to

    rule them all • Common subset across all platforms
  17. Portable Library Tools • Pros • One class library to

    rule them all • Common subset across all platforms • Cons
  18. Portable Library Tools • Pros • One class library to

    rule them all • Common subset across all platforms • Cons • No Pre-processor Directives
  19. Portable Library Tools • Pros • One class library to

    rule them all • Common subset across all platforms • Cons • No Pre-processor Directives • No platform specific-code
  20. Portable Library Tools • Pros • One class library to

    rule them all • Common subset across all platforms • Cons • No Pre-processor Directives • No platform specific-code • Limited API set - no System.Xml.Linq or System.Net.WebClient
  21. Project Linker • Pros • Auto-link files between projects •

    Cons • Does not work with MonoDevelop • Must have all projects in the same solution
  22. StringBuilder builder = new StringBuilder(); String lineSep = System.getProperty("line.separator"); ContentResolver

    content = getContentResolver(); Cursor ncursor = null; try { ncursor = content.query (ContactsContract.Data.CONTENT_URI, new String[] { ContactsContract.Data.MIMETYPE, ContactsContract.Contacts.LOOKUP_KEY, ContactsContract.Contacts.DISPLAY_NAME }, ContactsContract.Data.MIMETYPE + "=? AND " + ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME + "=?", new String[] { ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE, "Eric" }, null); while (ncursor.moveToNext()) { builder.append (ncursor.getString(ncursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)) + lineSep); String lookupKey = ncursor.getString (ncursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)); Cursor dcursor = null; try { dcursor = content.query (ContactsContract.Data.CONTENT_URI, new String[] { ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.Data.DATA1 }, ContactsContract.Contacts.LOOKUP_KEY + "=?", new String[] { lookupKey }, null); while (dcursor.moveToNext()) { String type = dcursor.getString (ncursor.getColumnIndex(ContactsContract.Data.MIMETYPE)); if (type.equals (ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) builder.append ("Phone: " + dcursor.getString(dcursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)) + lineSep); else if (type.equals (ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) builder.append ("Email: " + dcursor.getString(dcursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA1)) + lineSep); } builder.append(lineSep); } finally { if (dcursor != null) dcursor.close(); } } } finally { if (ncursor != null) ncursor.close(); } t.setText(builder.toString());
  23. var builder = new StringBuilder(); var abook = new AddressBook(this);

    foreach (Contact c in abook.Where (c => c.FirstName == "Eric" && c.Phones.Any())) { builder.AppendLine (c.DisplayName); foreach (Phone p in c.Phones) builder.AppendLine (String.Format ("{0}: {1}", p.Label, p.Number)); builder.AppendLine(); } Console.WriteLine (builder.ToString());
  24. StringBuilder builder = new StringBuilder(); String lineSep = System.getProperty("line.separator"); ContentResolver

    content = getContentResolver(); Cursor ncursor = null; try { ncursor = content.query (ContactsContract.Data.CONTENT_URI, new String[] { ContactsContract.Data.MIMETYPE, ContactsContract.Contacts.LOOKUP_KEY, ContactsContract.Contacts.DISPLAY_NAME }, ContactsContract.Data.MIMETYPE + "=? AND " + ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME + "=?", new String[] { ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE, "Eric" }, null); while (ncursor.moveToNext()) { builder.append (ncursor.getString(ncursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)) + lineSep); String lookupKey = ncursor.getString (ncursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)); Cursor dcursor = null; try { dcursor = content.query (ContactsContract.Data.CONTENT_URI, new String[] { ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.Data.DATA1 }, ContactsContract.Contacts.LOOKUP_KEY + "=?", new String[] { lookupKey }, null); while (dcursor.moveToNext()) { String type = dcursor.getString (ncursor.getColumnIndex(ContactsContract.Data.MIMETYPE)); if (type.equals (ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) builder.append ("Phone: " + dcursor.getString(dcursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)) + lineSep); else if (type.equals (ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) builder.append ("Email: " + dcursor.getString(dcursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA1)) + lineSep); } builder.append(lineSep); } finally { if (dcursor != null) dcursor.close(); } } } finally { if (ncursor != null) ncursor.close(); } t.setText(builder.toString()); Manually in Java
  25. var builder = new StringBuilder(); var abook = new AddressBook(this);

    foreach (Contact c in abook.Where (c => c.FirstName == "Eric" && c.Phones.Any())) { builder.AppendLine (c.DisplayName); foreach (Phone p in c.Phones) builder.AppendLine (String.Format ("{0}: {1}", p.Label, p.Number)); builder.AppendLine(); } Console.WriteLine (builder.ToString()); Xamarin.Mobile for Android
  26. var builder = new StringBuilder(); var abook = new AddressBook();

    foreach (Contact c in abook.Where (c => c.FirstName == "Eric" && c.Phones.Any())) { builder.AppendLine (c.DisplayName); foreach (Phone p in c.Phones) builder.AppendLine (String.Format ("{0}: {1}", p.Label, p.Number)); builder.AppendLine(); } Console.WriteLine (builder.ToString()); Xamarin.Mobile for iOS
  27. var builder = new StringBuilder(); var abook = new AddressBook();

    foreach (Contact c in abook.Where (c => c.FirstName == "Eric" && c.Phones.Any())) { builder.AppendLine (c.DisplayName); foreach (Phone p in c.Phones) builder.AppendLine (String.Format ("{0}: {1}", p.Label, p.Number)); builder.AppendLine(); } Console.WriteLine (builder.ToString()); Xamarin.Mobile for Windows Phone 7.1
  28. The Future Personal Ideas • MonoTouch support for Visual Studio

    / Able to open WP7 projects in MonoDevelop • File -> New Cross-Platform Application • One “MonoMobile” class library for iOS, Android and Windows Phone 7 • Analyser tool for existing libraries