Monday 18 July 2011

Xamarin welcomes MonoTouch and MonoDroid "home"

Great news! Xamarin has acquired a "broad, perpetual license" to the MonoTouch and Mono-for-Android work that was done while the dev team was part of Novell (prior to the Attachmate buyout kerfuffle). There's a press release on the Novell website and Miguel posted on his blog too. Congratulations to the Xamarin team!

Check out the product details at:
Start with the iOS Roadmap to find out what's coming up next.

Monospace is going to be great! Have you downloaded the app yet :-) ?

Wednesday 13 July 2011

"M"osetta Stone II: ViewController → Activity

After my recent posts I received a question asking for tips on porting a MonoTouch app to MonoDroid. I'm going to take a crack at that over a couple of days - with the warning that you probably shouldn't rush out and buy either tool but wait for Xamarin's future Mono-on-iOS and Mono-on-Android products.

The purpose of the original "M"osetta Stone post was to give cross-platform developers a 'head start' with some high-level concepts. This post will look a little closer at a screen from the Monospace11 app: the Speakers list.


This may be a massive oversimplification, but...
if you have
___ in iOS
then you want
___ in Android
to
UIViewControllerActivitysubclass to present a screen/form/page to the user
ViewDidLoad()OnCreate()setup the UI
Add() or AddSubview()SetContentView()use in ViewDidLoad/OnCreate to 'attach' UI to display
ViewWillAppear()OnResume()load/re-load data that might change and bind to UI
UITableViewListViewvisual control that presents a scrolling list
UITableViewSourceAdaptersubclass to broker the display of a data collection to the UI
GetCell()GetView()to build the layout(UI) for each cell/row, including re-using cells/views for performance
RowSelected()ItemClick EventHandlerperform an action when a row is touched
RowsInSectionCounttell the table/list how many rows to cater for

Here's how it looks in a Visual Studio Class Diagram*
* I've greyed out some of the methods not relevant to the discussion - the iOS implementation of the alphabetic index down the right edge doesn't have an Android equivalent, for example

Notes:
  • UITableViewSource has been implemented as an nested class to resemble the iOS pattern of implementing the equivalent Obj-C protocols on the ViewController - this pattern makes no sense in Android so the classes are separate.
  • The MonoTouch example code builds the UI in C# (eg. tableView=new UITableView();AddSubview (tableView);) whereas MonoDroid loads layout XML files SetContentView(Resource.Layout.Speakers);. This can happen in both ViewDidLoad/OnCreate and GetCell/GetView where UI controls must be created and presented to the user.
  • The 'touch event handler' is in a different class: in MonoTouch the TableViewSource handles a touch for a specific row (NSIndexPath); MonoDroid implements the ItemClick EventHandler<ItemEventArgs> on the ListView for a given GetRow(e.Position).
  • Both examples use the constructor (TableViewSource/SpeakersAdapter) of the 'broker' class to pass the actual business object collection for display. This pattern lets the data be filtered/sorted/whatever before being passed in for display.
  • Calling refreshSpeakers() from ViewDidLoad/OnResume is kinda redundant in this example since the list never changes - but in other spots (eg the Favorites screen) you would want to refresh the list each time because it may have changed.

The Code
You can have a look at the MonoTouch code SpeakersViewController.cs and the MonoDroid SpeakersActivity.cs, SpeakersAdapter.cs to see the actual implementation. For MonoDroid you'll also need to check out the layout XML files Speakers.axml and SpeakersItem.axml.

One more thing...
One final piece which takes some getting used to... in MonoTouch this screen is part of a UINavigationController stack and your RowSelected creates a new ViewController object (passing whatever parameters you need) and calls NavigationController.PushViewController(). The ViewController instances in the navigation stack are 'stateful' and it is really easy to pass business objects around as parameters.
In MonoDroid, the ever-present 'back-stack' does not require a specific 'navigation controller' BUT at it's simplest the mechanism is much more primative and involves passing simple type parameters (eg. strings) like this
var intent = new Intent();
intent.SetClass(this, typeof(SpeakerActivity));
intent.PutExtra("Name", speaker.Name);
StartActivity(intent);

There are more sophisticated approaches but it is probably best to keep your parameter-passing to a minimum - this way the Android hardware 'Back' button "just works".

HTH Slava ;-)

Monday 11 July 2011

MonoDroid v MonoTouch : a comparison

The past few days I've posted MonoDroid and MonoTouch apps for Monospace - and while they aren't perfect examples of the sort of code-sharing and efficiency that's possible with Mono I thought it would be interesting to compare them as the functionality they offer is very similar.

First, these are the high-level code metrics (as calculated by Visual Studio):
Unfortunately I didn't align the namespaces very well. Here's the explanation:

Total lines of code (TLOC)
Mono-for-Android: 802 lines
MonoTouch: 1,420 lines (2,033 - 613 in SQLite)
At first glance, the MonoDroid app 'wins' with just half the code of the MonoTouch version. I've ignored the SQLite library and the MonoTouch.Dialog framework as they aren't "user code", and any non-.cs files (eg XML markup).

Common code
Although difficult to 'see' because I've rushed these codebases into the public domain, there is a bit of 'code re-use' in these apps (ie. it was only written once, and the c# shared across both platforms using the power of Mono :)
ConfXml == MIX10Xml == approx 200 lines of business objects (DTOs mainly) that match the serialized conf.xml format that is the shared data structure for both platforms.
The ConceptDevelopment.Kelvin code is also shared (different sizes in each aren't relevant for now).

Removing the common code from the comparison results in these totals:
Mono-for-Android: 575 lines (802-199-28)
MonoTouch: 1,145 lines (1,420-178-97)

"Re-used" code
Mono-for-Android's Main.cs::DeserializeConferenceFile, LoadWhatsOn and MonoTouch's AppDelegate.cs::FinishedLaunching both contain "very similar" code in the form of the conf.xml deserializer and parser. In MonoTouch it's 70 lines and in MonoDroid it's 307 lines. The MonoTouch version is heavily assisted by the Linq/MonoTouch.Dialog code in HomeController (another 150 lines or so) which explains part of the difference... but what is shared is the deserialization logic and a number of Linq statements that help parse it for display. These would be harded to shift into a common library due to the dependency on MonoTouch.Dialog - but there was definitely an efficiency gain by having the code already written and tested on one platform before porting to the other. I'll adjust both by the same 'average' LOC count to try and reflect the 'copy/paste but modify' efficiency gain.

Mono-for-Android: 375 lines (575-200)
MonoTouch: 945 lines (1,145-200)

Feature parity
Adjust the MonoTouch solution to allow for the fact that it implements the Map feature that is not available on MonoDroid - 118 lines of code across a few classes.
MonoTouch: 827 lines (945-118)

What's left?
Once we've removed the libraries, the shared data structure, common code and allowed for some "copy/paste re-use", what's left to differentiate the two codebases? Basically just the UI and the code that binds our DTOs to it.
Mono-for-AndroidMonoTouch (iOS)
Code375 lines827 lines
'markup'14 AXML1 XIB
Views7 Activities9 ViewControllers
DataSources6 Adapters5 TableViewSource
Some notes on the difference:
  • There are 350 lines of AXML to define the layouts used in MonoDroid - the equivalent task in MonoTouch is done mostly in C#, significantly contributing to the LOC difference. I could have implemented a lot of that MonoTouch layout in XIBs using InterfaceBuilder - I just don't like doing it that way.
  • The UITabBarController takes more code to setup than
    OnCreateOptionsMenu.
  • The iOS SQLite implementation of saving Favorites is more verbose than the XML-serialized-file solution used on Android.
  • The MonoTouch source is almost 2 years old, and in some places isn't as succinct as it could be.

Conclusion
So is MonoTouch instrinsically more verbose than MonoDroid? I don't think so - it depends greatly on your preference for constructing your Views (XIBs or in-code). The more important question: does building with Mono* make it easier to port your app to other mobile platforms... and the answer is YES! In future this code might get tidied up into a good example of a cross-platform app... in that case I'll re-examine the stats to make an even better case.

Look at it this way: the iOS app took 1,400 lines of code (it was written first). For an additional 375 LOC (plus some layout XML) we got an Android port - almost for free!

Thankfully it sounds like Xamarin Studio is coming along nicely.

Saturday 9 July 2011

MonoTouch for Monospace II

Further to the MonoDroid version, I've just submitted an iOS version of the Monospace 2011 conference app to Apple (fingers crossed it gets approved, and in time for the conference!).

Here's how it looks:

Even if it doesn't get approved in time, the code is open-source and can be found at github.com/conceptdev/Monospace11. It is based on the original Monospace09, PDC09 and MIX10 apps. A couple of guys helped out with the MIX10 version: @migueldeicaza, @kangamono and @chrisntr. I know Miguel in particular was keen for this code to be open-sourced... I think (?) it was one of the first outings of his awesome MonoTouch.Dialog library. I'd like to thank them again for their help (and to note that any remaining bugs or problems are mine). Also note: there is some old code in there (like, almost 2 years)... it scares me a little to put it up on Github, so please, be gentle.

I'll update with an AppStore link if/when Apple is done; but for now just enjoy the code :)

See you at Monospace!

Wednesday 6 July 2011

MonoDroid for Monospace

Waay back in 2009 I threw together MonoTouch for Monospace as an early example of using C# on the iPhone using MonoTouch.

Fast-forward two years... to MonoDroid for Monospace:

The schedule for Monospace 2011 was just announced today, and since there didn't seem to be a mobile app announced along with it I've re-used some old code to get a basic Android app working using Mono for Android.

Download/try it out
You can install Monospace11 from the Android Market

OR

Download the Mono for Android code from Monospace11 on Github

and visit the 'homepage' at monospace11.confapp.com

Leave any comments or feedback below.

Tuesday 31 May 2011

OzALT.NET MonoDroid Presentation

Slides from tonight's OzALT.NET '20 minute' presentation on Mono-for-Android. I didn't actually make it through all the slides, but we got through a few demos including this simple HelloWorldActivity.cs example and the Restaurant Guide demo.

Also enjoyed @thomasjo's pres on CoffeeScript and Joshua Roth talking about NBuilder.

Friday 27 May 2011

Mobile UI Design ramblings...

Mobile UI design has come up a couple of times the past few days (as has Xamarin),
  • I'm looking to port an existing iOS app to Android - how 'same' should it look?
  • Nielsen Norman Group released their latest Useability of iPad Apps and Websites report
  • Ongoing discussion with @russaus
...so seemed like a good time to make some notes (and for UI, read UX and IA as well :)

Porting apps...
Porting apps from one platform to another (iPhone to Android, iPad to Android, or to Windows Phone, or from 'web', etc) always brings with it a challenge to make each version feel 'native' and embrace the platform's UI idioms & metaphors (while simultaneously re-using as much code as possible and keeping your application consistent across each). This can be seen in previous posts on the MIX11 app and the Restaurant Guide sample being ported to iPhone, Android and Windows Phone 7. Should the new Android app be a 'UI clone' of the iOS version? Should it be redesigned from scratch, removing any traces of iOS-ness? The answer is probably somewhere in between, being guided by your usability and branding goals, and by feedback from your users.
UPDATE: some thoughts on Why Are Android Apps Ugly? :-)

"Usability of iPad Apps and Websites": 2 reports
Coincidentally, while planning the UI for the Android app, Nielson Norman Group released an updated Usability Report for iPad Apps and Websites. The new edition (and the previous) are great reads (free to download) - some points will seem obvious, some will trigger "a-ha" moments and other's you'll disagree with; but overall you'll probably find it worthwhile to download them both.

References...
There are a couple of great websites worth looking at when you are doing UI design
  • mobile-patterns.com is a cool collection of screenshots from iPhone apps grouped into 'UX categories' like User Profiles and Lists. My favorite is Empty Data Sets - so often overlooked! (by @mari18)
  • ui-patterns.com is a more general collection (ie. not mobile) with categories like Getting Input and Navigation. It is a LOT deeper in terms of content (articles/discussion as well as screenshots) and likely to be thought-provoking no matter what platform you're working on. (follow @uipatternscom
  • UPDATE: Windows Phone 7 for Designers — Cheat Sheet kinda similar to the mobile-patterns site above but for Windows Phone. Poster-layout for easy printing/reference (by @teppo).


...and what about that whole MonoTouch/MonoDroid 'thing'?
Novell (Attachmate) says (my underline)
Focusing on what matters most to customers is the key to our innovation strategy and will drive the growth of our business. This has meant reductions in certain areas, such as Mono. However, Mono remains part of the SUSE business and should customer demand for Mono products accelerate, our development efforts will rapidly respond. Regardless, we will continue to provide maintenance and support for all Mono products – MonoTouch, Mono for Android, Mono Tools for Visual Studio and SUSE Linux Enterprise Mono Extension.
But it sounds disingenuous considering they have already sacked the entire team... and WTF does "should...demand...accelerate" mean? How is demand going to grow when they've killed any chance of enhancing the product and do not market it?? If they were truly "Focusing on what matters most to customers" they wouldn't have sacked the engineers in the first place, or else should have released/sold/transferred the Touch/Droid IP to Xamarin where it has some hope of a future (IMHO, anyway). </2centsworth>

Also, in related news, @migueldeicaza announced that Nat Friedman has joined Xamarin as CEO. Nat previously worked with Miguel as a co-founder of Ximian.

p.s. I'm *guessing* that we will be saying goodbye to the MonoTouch and Mono for Android product names since Novell probably owns them... wondering what I should use for Twitter hashtags now to replace #monotouch and #monodroid? Something with an 'X'? :)

Tuesday 17 May 2011

MonoTouch/MonoDroid and Xamarin - what now?

If you are in the mono community then you'd have to be living under a rock not to have read that Novell was purchased by Attachmate then (first) heard the rumors that Attachmate Lets US Mono Developers Go and (second) seen Miguel's confirmation/announcement of the creation of Xamarin.

What I think this means is:
  • Mono should be fine. It has always been open-source (see github.com/mono) and receives contributions from a variety or people regardless of who they work for.
  • The MonoTouch and Mono for Android (aka MonoDroid) products published by Novell will effectively stop being supported "as of now". This is based on the fact that none of the devs work there any more.
  • Attachmate hasn't announced any plans for those products - even whether they'll continue to be available for sale (along with the associated activation servers). It's impossible to predict what will happen here... various people are trying to get answers from Novell/Attachmate. Personally, even if Attachmate attempted to continue selling/supporting the products I would choose not to be their customer as soon as alternatives are available.
  • Miguel and the team who built MonoTouch and MonoDroid have publicly announced they're working on comparable/compatible products to be sold by Xamarin (their new company). These new products are 3-4 months away, betas first prior to a real release. They've done it before, they can do it again!
Lots of people (myself included) have invested plenty of time and money purchasing, learning and using MonoTouch and MonoDroid. I even helped write a MonoTouch book (and some guys have been busy with a MonoDroid one too). We are all collectively upset, disappointed and angry (imagine how the devs themselves feel).

All of this uncertainty has provoked a number of reactions, among them suggestions that all the work done on MonoTouch/MonoDroid projects to-date has been wasted or that people should start learning the native SDKs for iOS and Android instead of committing to the Mono alternatives.


Learning the native SDKs has always been an option for anyone interested in mobile dev, but who wants to go to all that effort!? The value proposition for Mono* remains: .NET developers can leverage their existing language and framework knowledge AND code can be written once and re-used across three platforms (iOS, Android and Windows Phone). Those advantages continue to be true - the two products are definitely useable right now (MonoTouch obviously more mature than MonoDroid) - and if you care to take Miguel at his word they have a 'compatible' future. So what to do in the next 3 or 4 months...

I already have a MonoTouch/MonoDroid app written and published (or almost published)
Keep going! If everything is working for you right now, why change? In future you "might" need to port your work to native IF Xamarin's products are late/don't work. But if you start porting now and spend three months doing the conversion and Xamarin succeeds then you'll have wasted a lot of effort! What's more, your existing codebase will form an excellent 'regression test' for the Xamarin previews/betas... make sure you sign up at xamarin.com and participate! Your knowledge and experience with the existing products will be very helpful testing the new bits.

If you are really pessimistic you can still continue on this path - but maybe allocate some of your dev time learning the native SDKs and possibly prototype/porting some of your code. Don't do all of it - just get comfortable with the fact that it's possible while waiting to see how Xamarin develops.

I have purchased MonoTouch/MonoDroid and was planning to use them in future
Why not give them a try anyway? There are multiple benefits of using Mono*, including learning the native SDK APIs from the comfort of a language you know and also being productive more quickly. Think of it like prototyping - you get something working quickly and along the way learn a lot that can be re-used (you WILL learn the iOS/Android APIs).

If your app is single-platform I can imagine this decision might be a close call (and perhaps you should just learn Objective-C or Java) BUT if you are planning a cross-platform solution then you are still going to save time and effort with Mono* and code-sharing. One obvious risk would be the possibility of hitting something that isn't supported/doesn't work in Mono* yet - so do your research.

On the other hand, imagine spending the next few months learning BOTH Objective-C and Java, and producing two incompatible codebases for your app, only to discover that Xamarin rocks!

I'm a consultant and I've recommended MonoTouch/MonoDroid to clients
Ouch. This is bound to 'look bad' since the less your clients understand about the risk/reward of a tool like Mono*, the more they are going think you've stuffed up. In reality, though, the above points still apply - you can offer them the same bet: switch tools now and potentially waste some time or risk 'maybe' porting at a later time but take advantage of the benefits Mono* provides now... after all you recommended Mono* for a reason and many of those reasons are still valid.

I have done this myself - so I know how uncomfortable it feels.

I am interested in MonoTouch or MonoDroid but haven't purchased yet
This is a tough one. I'm not sure that the Novell Shopping Cart or the Activation Server are even working at the moment (activation behind an authenticating proxy is not supported at all). Even if they were, I'm not sure I'd want to give Attachmate my money. Maybe this will become clearer in the coming days/weeks.
You can definitely try out the 'free trial' (emulator only) editions but for a real project that you want to publish on AppStore/Marketplace soon I'm afraid you might need to consider learning the native SDKs or waiting a while... :-(

In conclusion...
I'll be the first to admit this is a very "glass half-full" point-of-view. Lots of bad s**t could happen: support issues with the current products that can't be resolved, legal issues with Attachmate, product delays from Xamarin, unexpected costs or incompatibilities for the new stuff, etc, etc, etc.

At the end of the day, you'll make a decision based on your risk-averse-ness (triple word score!) regardless of my rainbows and unicorns. Just keep in mind that the apparent 'end of life' of the current MonoTouch/MonoDroid products, while sad, is not (yet) the end of the world. In some ways, you can best support Xamarin by continuing to use the existing tools so that you've got something to migrate to their new stuff.

Make sure you've got some peanuts and a towel, and above all DON'T PANIC.

Saturday 7 May 2011

Mobile Camp Oz

Went along to Mobile Camp Oz today, saw some great presentations from @dglover, Scott Vandonkelaar and @markaufflick as well as an interesting keynote by Darren Burden of Fairfax Media. Thanks to the speakers for their time and also to everyone that came along to watch (finally special thanks to Nick for organising and convincing me to come along!).

As for my pres, here are the slides:
and you'll find example source at github.com/conceptdev. The pres was a bit slide-heavy... will do more live-code/examples next time.

Also check out these past posts:
Finally - check out the result of Scott's presentation on the Android Market Mobile Camp Oz!

Monday 11 April 2011

MIX11... the mobile app collection

It's that time of year again - MIX11 conference time - and although last year there was just one mobile app (MIX10 for iPhone), this year conference delegates are spoilt for choice!

This year there are Conf-powered apps on the three biggest mobile platforms: iPhone, Windows Phone 7 and Android...

All are pure .NET projects - the Windows Phone 7 app uses the Microsoft Windows Phone SDK while the iOS and Android versions are bought to you via power of Mono: MonoTouch and Mono for Android

The official 'site' for these apps is mix11.confapp.com - it also lists a couple of 'other' options for Windows Phone users. Download one or all of them - and have a great time at MIX!

Aside: for those working on cross-mobile-platform UI, the primary navigation mechanism is quite different across the three platforms (my thoughts):
  • iOS uses a 'tab bar', familiar to all users as it features in most iOS apps. The benefits are that it's always visible and the icon appearance is consistent and attractive. Only five options fit before they get hidden behind a 'More...' link.
  • Windows Phone 7 uses the 'panorama' control. While it encourages discovery by panning across pages, not all options are immediately obvious to the user. Microsoft suggests a maximum of seven pages, so beyond that limit you need to think of other navigation paths.
  • Android uses the operating-system provided 'hardware menu'; it is not visible until the user presses the button however it can then display a number of options at once (similar to iOS). Because it can be context-sensitive the user doesn't really know what options to expect until they press the button (although the MIX11 app uses a consistent menu from all pages to get around this confusion).

Saturday 5 March 2011

"M"osetta Stone

Some more thoughts on cross-platform mobile development (MonoTouch, MonoDroid and Windows Phone 7) from yesterday's post - a 'rosetta stone' (not this one) to translate between the three platforms (Not that each of these things is exactly equivalent - they're matched up where the concept/role/function seems similar to me).
iOSWP7Android
"View"XIB (Interface Builder)Xamlaxml
UIViewControllerPhoneApplicationPage (codebehind)Activity
n/a (UIAutoResizing)StackPanelLinearLayout
UITableViewListBoxListView
UITableViewCellListBox.ItemTemplaten/a (any view)
UITableViewSourcen/a (binding, IEnumerable)BaseAdapter
Navigation "Controller"NavigationController. PushViewController()NavigationService.
Navigate()
StartActivity()
n/a (object)Xaml UriIntent.SetClass()
n/a (object properties)Xaml Uri querystring paramsIntent.PutExtra() .AddFlags()
n/a (object properties)NavigationContext
.QueryString
.TryGetValue()
Intent .GetXXXExtra()
ThreadingInvokeOnMainThreadDispatcher.BeginInvokeRunOnUiThread
"Model"C# .NET objects - shared thanks to Mono on iOS & Android. Also WebClient, Linq, Generics, Xml, Serialization, etc... :-)

One major difference between iOS and the other two (both in terms of coding and also UI design) is the presence of hardware buttons and the back-stack.

Hardware buttons
The most important hardware button is Back (covered next) however Android's Menu button is also significant for the impact is has on UI design compared to iOS and WP7. Both Apple and Microsoft's designers like the application menu (UITabBarController, ApplicationBar) to be permanently visible. Google, on the other hand, provides the Menu button to show the menu, meaning that most of the time it is hidden. This means your Android app UI might need to provide other visual clues so that navigation/features/options are more discoverable.

Back stack
Both Android and WindowsPhone7 devices have a hardware Back button supported by the respective SDKs via the 'back-stack' which is analogous to your web-browser History: each "View" has an "address" (a Xaml Uri in WP7, an Intent in Android) which is stored as the user navigates through your application. At any time (unless you intercept it) the hardware Back button allows the user to cycle back through previous views until they have exited your app.

iOS utilises a similar navigation metaphor in its UINavigationController - however the back button is 'soft' (displayed in the top-left corner of the screen) and the scope is limited to the set of views that the developer chose to include in that navigation context.

MonoDroid meet MonoTouch & WindowsPhone7

This post follows the previous one about building for MonoTouch and WindowsPhone7 by porting the example to Google's Android platform using MonoDroid.

Here's how it looks (no need to identify which platform is which :)

As before, the code is available on github/conceptdev/RestaurantGuide - for comparison here is a shot of the three .sln files.


A couple of observations:
  • One of the reasons the iOS/MonoTouch solution is so 'neat' is because I have not used the 'UI Designer' for that platform (ie. Interface Builder) so there are no 'markup' files for the user interface (ie. .xib files). The entire layout is done in C# for the MonoTouch example, whereas the WP7 and Android version use Xaml and axml respectively.
  • These examples 'just work' - they don't claim to be best-practice in designing an app for any of these platforms*.

* for a quite neat cross-platform design (at least across MonoDroid and WP7) see @gshackles TwitterSearcher sample

p.s. does anyone know what the Android equivalent of an "indexed list" is? Pls comment or @conceptdev... thx

Sunday 27 February 2011

Random tip: wtf is"7 CDCs" and debugging on a Samsung Galaxy Tab

Just a quick note on some issues I had debugging a MonoDroid app I've been playing with (MonoDroid is very cool, BTW)... for some reason I couldn't get a Samsumg Galaxy Tab to be recognised as a USB device when connected to my 64-bit Windows 7 PC.

Googling turned up a few different 'ideas' like Samsung Galaxy S Problems, Samsung Kies Software and PC connectivity and Connect Samsung Galaxy S with Kies on your PC - The MTP Error. None of those suggestions worked for me, despite a lot of mucking about with driver installs.

It turned out a hint in this post on USB connection trouble fixed my problem... "somehow" the device's USB port was set to 'modem mode' and I had to type *#7284# on the phone keypad to re-set it! Un-in-tuitive!



The Kies Samsung software/drivers off the Samsung website were fine, once the device was in 'USB mode'.

Anyway, hope that helps someone else...

Friday 18 February 2011

Status Update: accessing Facebook with MonoTouch

Haven't blogged for a while, but hopefully that's about to change... and to kick off more regular posts here is a simple example of accessing the Facebook OpenGraph API using MonoTouch.

The core of the example is @redth's MonoTouch.Facebook.Authorization ViewController which uses the Facebook OAuth webpage hosted in a UIWebView to authenticate and grab the access_token you need for subsequent requests.

The app looks like this when it runs (and yes, when you Save your status update, it appears directly on your Facebook Profile):
The code is available on github at github.com/conceptdev/Facebook - remember you need to have a Facebook Application 'Client ID' (create one here) to get it working. NOTE: this is a sample - there is very little in the way of error detection, correction or recovery... left as an exercise for the reader :)

Facebook Login
The Facebook OAuth 'magic' happens inside a UIWebView... we create one and navigate to https://graph.facebook.com/oauth/authorize which displays and processes the login form. A successful authentication results in a redirect to a 'known page'; the redirected URL contains the access_token needed for subsequent 'authorised' requests so the code strips it out and saves it. Thanks again to Jon without whom the rest of the code wouldn't be here!

Facebook Newsfeed
Getting the news feed is relatively simple and thanks to some useful info on using Json.NET with MonoTouch it is easy to parse too!
var b = wc.DownloadData(
   new Uri("https://graph.facebook.com/me/home?access_token=" + token));
var s = Encoding.UTF8.GetString(b);
var posts = JsonConvert.DeserializeObject<Posts>(s);
The parsing works so easily because Objects.cs contains a set of classes that (roughly, not completely) match the JSON returned by Facebook, for example:
{"data":[\{"id":"57755305836_10150135900140837","from":\{"name":"Tiga","category":"Musician\\/band","id":"57755305836"\},
"message":"Bad DJ Signs Vol.1:  when your dancefloor reminds you of the \\"club\\" scene from \\"Vanilla Sky\\"",
"icon":"http:\\/\\/photos-d.ak.fbcdn.net\\/photos-ak-snc1\\/v27562\\/23\\/2231777543\\/app_2_2231777543_9553.gif",
"actions":[\{"name":"Comment","link":"http:\\/\\/www.facebook.com\\/57755305836\\/posts\\/10150135900140837"\},
\{"name":"Like","link":"http:\\/\\/www.facebook.com\\/57755305836\\/posts\\/10150135900140837"\},
\{"name":"\\u0040ciaotiga on Twitter","link":"http:\\/\\/twitter.com\\/ciaotiga?"\}],
"type":"status","created_time":"2011-02-18T07:23:42+0000","updated_time":"2011-02-18T08:25:22+0000",
"likes":33
maps to
The DeserializeObject() call is then all that is required to take the JSON string and turn it into an object graph that is easily bound to a UITableView (see Main.cs).

Facebook Status Update
Once we have the authentication token updating your status is easy - a simple POST using WebClient is all it takes.
System.Net.WebClient wc = new System.Net.WebClient();
var result = wc.UploadString
("https://graph.facebook.com/me/feed?access_token=" + token
, "message=" + status);


but isn't there a Facebook API for iOS?
Yes, in addition to this 'manual' way of authenticating using an embedded webpage Facebook also provides a Mobile API. The UI presented to the user looks nicer than the webpage AND it can interact with the official Facebook app (if installed). To get that working with MonoTouch requires btouch-library bindings... but that's a story for another post.

UPDATE: (from comments below) @klmcmahon has already ported the Facebook iOS SDK and sample to MonoTouch - thanks Kevin!