Upload
jonas-folleso
View
6.851
Download
1
Tags:
Embed Size (px)
DESCRIPTION
With mobile taking off in a big way it is a fun and exciting time to be a software developer. The landscape is rapidly changing, with a wide variety of options for platforms and programming languages. Businesses are faced with tough decisions on how to provide a best possible user experience, yet keeping maintenance cost down across the different smart phone platforms.Some are compromising user experience and betting on web based interfaces, while others require the high fidelity user experience or device integration traditionally only found in native apps.In this session I will demonstrate how we can write fully native applications taking full advantage of the platform, yet achieving a high level of code reuse across Windows Phone 7, Android and iOS.Topics covered:- Separated Presentation patterns for maximum code reuse across all platforms- How to structure your source code and build it for all platforms- How to access devices specific functionality like Camera, GPS and Accelerometer in a cross platform way- Tips, tricks and tools to make the cross platform development process smoother.For maximum benefit from this session some prior knowledge of MVVM is beneficial.
Citation preview
Cross platform mobile apps using .NET
Jonas Follesø
NDC, June 2011
http://www.flickr.com
/pho
tos/20792787@N00/2248623391/
AGENDA:
•Why?
•8 techniques
•Complete example
TILE FLOOD
TILE FLOOD
Why cross platform..?
REUSE SKILL SET?
private void open_Click(object sender, RoutedEventArgs e)
{ var channel = HttpNotificationChannel.Find("NNUG");
if (channel == null)
{
channel = new HttpNotificationChannel("NNUG");
}
channel.ChannelUriUpdated += channel_ChannelUriUpdated;
channel.ShellToastNotificationReceived +=
channel_ShellToastNotificationReceived;
channel.Open();
}
REUSE CODE?
REUSE LIBRARIES
• +35 libraries monotouch.info/MonoTouch/Libraries
COST OF MAINTAINING
MULTIPLE CODE BASES
LIKE C#..?
... OR DISLIKE THE ALTERNATIVE
OBJECTIVE-C: DATE (NO TIME)+ (NSDate *) stripTime:(NSDate *) date { NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorian components: (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date];
date = [gregorian dateFromComponents:components];
[gregorian release];
return date;}
C#: DATE (NO TIME)
public DateTime StripTime(DateTime date){ return date.Date;}
TECHNIQUE 1:
PORTABLE CLASS
LIBRARY
HELP YOU STICK TO A
COMMON SUBSET
PROS• One class library for all platforms• Helps you stick to a common
subset
CONS• No Preprocessor Directives• No Platform Specific Code in Class
Lib• Not directly supported on
MonoDevelop yet
PORTABLE CLASS LIBRARY
TECHNIQUE 2:
LINKED FILES
WORKS IN MONODEVEL
OP
PROS• Same code across all platforms• Ability to add platform specific
code• Preprocessor Directives
CONS• Need to manage multiple projects
LINKED FILES
TECHNIQUE 3:LINK FILES
USING «PROJECT
LINKER»
PROS• Auto link files between projects
CONS• Does not work in MonoDevelop• Must have all projects in same
solution
PROJECT LINKER
TECHNIQUE 4:VSMonoTouch
Open MonoTouch projects in
VS2010
PROS• Open and build (verify)
MonoTouch in VS2010
CONS• Not a «real» build• Some manual steps involved
VSMonoTouch
TECHNIQUE 5:PREPROCESSOR DIRECTIVES
using System.Net;#if MONOTOUCH || MONODROIDusing System.Web;#endif
PROS• Easily write platform specific code
CONS• Code smell• DRY – The #ifdefs tend to spread
PREPROCESSOR DIRECTIVES
demo
TECHNIQUE 6:ABSTRACT COMMON
FUNCTIONALITY
public interface IDispatchOnUIThread{ void Invoke(Action action);}
// Windows Phone 7public class DispatchAdapter : IDispatchOnUIThread{ public void Invoke(Action action) { Deployment.Current.Dispatcher.BeginInvoke(action); }}
// Mono for Androidpublic class DispatchAdapter : IDispatchOnUIThread{ private readonly Activity _owner;
public DispatchAdapter(Activity owner) { _owner = owner; }
public void Invoke(Action action) { _owner.RunOnUiThread(action); }}
// Monotouchpublic class DispatchAdapter : IDispatchOnUIThread{
private readonly NSObject _owner;
public DispatchAdapter(NSObject owner){
_owner = owner;}
public void Invoke (Action action){
_owner.BeginInvokeOnMainThread(new NSAction(action));
}}
PROS• Share even more code• Do not need preprocessor
directives
CONS• More abstractions in code
ABSTRACT FUNCTIONALITY
TECHNIQUE 7:LEVERAGE
MVVM ON ALL PLATFORMS
39
Ensure that any code that manipulates presentation only manipulates presentation, pushing all domain and data source logic into clearly separated areas of the program.
Martin Fowler, Separated Presentation, July 2006
41Separated Presentation
Patterns
42
Data & Domain Logic(Model)
UI(View)
Interaction (Controller/Presenter)
MVVM
PATTERN FOR
BINDABLE UI
Data Model
VIEW
XAML
Code-BehindEvent
Handlers
APP LOGIC IN CODE BEHIND IS HARD TO
TEST AND MAINTAIN
Data Model
VIEW
XAML
Code-Behind
VIEW MODEL
State + Operations
Change notification
Data-binding and commands
SEPARATE USING MVVM
public class ObservableAdapter<T> : BaseAdapter<T>{ private readonly Activity _context; private readonly ObservableCollection<T> _collection;
public ObservableAdapter(Activity context, ObservableCollection<T>
collection) { _context = context; _collection = collection; _collection.CollectionChanged += (o, e) =>
NotifyDataSetChanged(); }...
ListAdapter = new ObservableAdapter<Airport>(this, _viewModel.Airports);
public abstract class ObservableDataSource<T> : UITableViewDataSource{
public ObservableDataSource (ObservableCollection<T> collection, UITableView
tableView){
_tableView = tableView;_collection = collection;_collection.CollectionChanged += (o, e) => {
tableView.ReloadData();};
}...
PROS• Share even more code• Testable View Models
CONS• More abstractions in code• May not feel natural to platform
APPLYING MVVM
demo
TECHNIQUE 8:USE PRE-
BUILT ABSTRACTION
S
PHONE SPECIFIC
APIS?
htt
p:/
/ww
w.fl
ickr
.com
/ph
oto
s/h
ow
zey/2
88
04
55
76
2/
EXAMPLES
• Accelerometer• Camera• Compass• Geolocation• Notification• Storage• Contacts• And more...
MonoMobile.Extensions
http://www.flickr.com
/pho
tos/tambako/3974809361/
• https://github.com/chrisntr/MonoMobile.Extensions
• One common API for phone specific functionality across all three devices
• Inspired by PhoneGap(same API)
private void FindNearestAirport(){ var coordinates = new MonoMobile.Extensions.Geolocation(); coordinates.GetCurrentPosition(PositionAvailable);}
private void PositionAvailable(Position position){ Console.WriteLine("{0} {1}", position.Coords.Latitude, position.Coords.Longitude);}
private void FindNearestAirport(){ var coordinates = new MonoMobile.Extensions.Geolocation(); coordinates.GetCurrentPosition(PositionAvailable);}
private void PositionAvailable(Position position){ Console.WriteLine("{0} {1}", position.Coords.Latitude, position.Coords.Longitude);}
3x MonoMobile.Extensions.dll• MonoDroid -> MonoMobile.Extensions.dll• Implemented using LocationManager
• MonoTouch -> MonoMobile.Extensions.dll• Implemented using CLLocationManager
• Windows Phone 7 -> MonoMobile.Extensions.dll• Implemented using
GeoLocationWatcher
PROS• Share even more code• Same set of abstractions used in
multiple apps• Well known API
CONS• More abstractions in code• Smallest common denominator
ABSTRACT FUNCTIONALITY
DOES IT WORK IN
PRACTICE?
http://www.flickr.com
/pho
tos/kozloski/2306510520/
FLIGHTS NORWAY
MONITORARRIVALS
AND DEPARTURES
http://www.flickr.com
/pho
tos/svenwerk/2181849280/
demo
1. Portable Library2. Linked Files3. Project Linker4. VSMonoTouch5. Preprocessor Directives6. Abstracting Common
Functionality7. Leverage MVVM8. Using Pre-built Abstractions
SUMMARY
FORK ME ON
GITHUBgithub.com/follesoe/FlightsNorway
• Complete app for iOS, Android & WP7
• 56 page tutorial with step-by-step code.
BEKK CONSULTING ASSKUR 39, VIPPETANGEN. P.O. BOX 134 SENTRUM, 0102 OSLO, NORWAY.
WWW.BEKK.NO
Jonas FollesøScientist
+47 977 [email protected]