Wednesday, July 3, 2013

Working with PCL's in the latest Xamarin.Android

Recently Xamarin released version 4.7.10 alpha of Xamarin.Android, which stated:
"PCL support!
(Cross your fingers, sacrifice your favorite meal under the full moon, and your PCL projects should Just Work! Testing wanted.)"
So I kind of wanted to find out if it really was true, and it also happens to be that I am doing a project which needs to fetch something from the Internet, which is great to test out HttpClient in PCL's as well. The project also uses Stuart Lodge's fantastic MvvmCross framework, also with the new PCL stuff, and everything seems to work. However there are some things you have to work around until Xamarin releases tooling that allows you to reference PCL's in your Android and iOS projects in the Visual Studio plugin.

So what I have tried:
  1. Download MvvmCross from the GitHub Repo, and rebuild the whole thing with the new Xamarin.Android version.
  2. Create a new PCL Library project in either Xamarin Studio or Visual Studio. I choose to target WP8, Store apps and .NET 4.5.
  3. Grabbed prerelease Microsoft.Net.Http package for the PCL. This also imports some Bcl stuff which allows you to use Async in the PCL. Now you should be able to use HttpClient and Async, sweet!
  4. For the Android project, here what is tricky. VS will complain that the Android project does not support PCL's, but it is lying! What you can do is either manually add a reference in the .csproj file or open up the project in Xamarin Studio and do it there.
  5. You will also have to grab the DLL's from the packages folder in your solution and import System.Net.Http, System.Net.Http.Extensions and System.Net.Http.Primitives from the Microsoft.Net.Http NuGet package you downloaded. I took if from the portable-net40+sl4+win8+wp71 folder.
  6. Now do your MvvmCross stuff, I just bound a button to a Command in my ViewModel, which calls a method in a service, which then in turn uses HttpClient to fetch some stuff from a Web Service.
This should also work for Xamarin.iOS and also on WP7 and WP8, Store Apps etc. As long as you use Microsofts BCL and Http packages in your projects.

Made a video describing the whole thing in more details:
Sample code can be found in my GitHub repo

5 comments:

  1. Finally! A clear step by step info. Thanks!

    ReplyDelete
  2. step #4 is not clear to me though
    "What you can do is either manually add a reference in the .csproj file or open up the project in Xamarin Studio and do it there."

    Add a reference to what?

    ReplyDelete
    Replies
    1. So you add the reference to the PCL project in your Android project by either adding and ItemGroup description in the .csproj file for the Android project, which points at the PCL Library; or you go into Xamarin Studio and add the reference there, because it does not complain about the support of PCL's.

      Delete
  3. Does this works for iOS too?
    Thanks

    ReplyDelete
  4. Hi Tomasz,

    I'm getting an exception when the deserializer runs, I also tried download your sample from git, but I get the same exception. Any idea what is causing it?

    An unhandled exception occured.
    09-01 15:23:16.888 I/MonoDroid( 982): UNHANDLED EXCEPTION: System.MissingMethodException: Method not found: 'Newtonsoft.Json.JsonConvert.DeserializeObjectAsync'.
    09-01 15:23:16.888 I/MonoDroid( 982): at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[RottenTomato.Core.RootObject].Start[d__0] (RottenTomato.Core.d__0& stateMachine) [0x00000] in :0
    09-01 15:23:16.888 I/MonoDroid( 982): at RottenTomato.Core.RottenTomatoApi.GetMovieList (System.String searchTerm) [0x00000] in :0
    09-01 15:23:16.888 I/MonoDroid( 982): at RottenTomato.Droid.Activity1+<b__0>d__1.MoveNext () [0x0001e] in c:\Files\Visual Studio Projects\RottenTomatoSample-master\RottenTomato.Droid\Activity1.cs:28

    Any idea what I am doing wrong? Thanks!

    ReplyDelete