Wednesday, December 19, 2012

Cross-Platform, WinRT, MonoDroid, MonoTouch, MonoMac, PCLs and VS2012

I've been asked on Twitter about the latest state of PCLs, VS2012, VSMonoTouch, etc.

There's no way I could do that in 140 characters... so here's a longer answer....

Before you start...


The Productivity tools for VS2012 are essential - install them - tools like 'right-click to edit the csproj file' are incredibly useful!

http://visualstudiogallery.msdn.microsoft.com/d0d33361-18e2-46c0-8ff2-4adea1e34fef

Loading MonoTouch, MonoDroid, WP, WindowsStore, WPF, MonoMac projects in Visual Studio 2012


By Visual Studio 2012, I mean Professional Edition or better - give up on Express as there is no addin support in the free version.

WindowsStore and WPF projects are all supported out of the box by Visual Studio 2012

WP7.1, WP8 can be supported by adding on the WP SDK - http://dev.windowsphone.com/en-us/downloadsdk

MonoDroid projects can be supported by buying (or evaluating) the Mono for Android - http://xamarin.com/monoforandroid

For the best MonoDroid experience, you probably want to get the x86 Android emulator working - see instructions at http://docs.xamarin.com/Android/Guides/Deployment,_Testing,_and_Metrics/Configuring_the_x86_Emulator

Unfortunately I've had a lot of problems getting this running on the same machine as Windows 8/Windows Phone 8/Hyper-V... I hope you have better luck than I do - as a good emulator is a wonderful tool to have.

MonoTouch projects require a little tinkering to make them load - they require VSMonoTouch2012 - a completely unsupported installer for this is available on my SkyDrive account - http://sdrv.ms/U6FKrz - some hint at where it came from are on https://github.com/follesoe/VSMonoTouch/issues/13 - obviously you install this at your own risk.

To complete the install of VSMonoTouch you also need to follow the steps in the readme of https://github.com/follesoe/VSMonoTouch:
  •  "Copy the MonoTouch binaries from your Mac development environment..."
  • "Add a RedistList-folder ..."
Warning: See section below on some known issues in VSMonoTouch in VS2012.

For MonoMac/Xamarin.Mac I'm not aware of any way to load these in VS2012 at present.

For older targets like Silverlight and WindowsForms I've not tried anything yet.

Some known issues for VSMonoTouch 2012


I have found VSMonoTouch2012 to be *very* slow when VS first loads a new solution/project - eg. it took *hours* to load MvvmCross_All the first time. After this, however, it seems to work quite well.

The way MonoTouch references mscorlib is slightly different to the Microsoft way, so you may find you need to explicitly reference the MonoTouch mscorlib - see http://slodge.blogspot.co.uk/2012/05/if-you-install-visual-studio-11-and.html

There are some arguments that VSMonoTouch and MonoDevelop/MonoTouch have over project files. These especially seem to concern the TargetFramework - the fact that VSMonoTouch is set to 1.0 does confuse things (I think). I have seen some projects where I have had to hack in a build step for "The type or namespace name 'TargetFrameworkAttribute' does not exist" - see http://slodge.blogspot.co.uk/2012/09/the-type-or-namespace-name.html

One very bizarre problem I've had is with one of my System.Windows surrogate DLLs - for some reason this refuses to pick up my MonoTouch references at compile time (it is OK in intellisense). This has only occurred in one place so far - see the HACK_DO_NOT_FORWARD_ICOMMAND in  https://github.com/slodge/MvvmCross/blob/vnext/PortableSupport/System.Windows.Touch/System.Windows.Input/ICommand.cs - background to this is in http://stackoverflow.com/questions/13326794/typeforwardedto-refuses-to-work-for-system-windows-input-icommand-in-monotouch

Using PCLs


PCL v2 support is included with VS2012.

This includes support for WindowsStore, WP, XBox, etc.

To add MonoDroid, and VSMonoTouch PCL support, you need to add some files (based on http://jpobst.blogspot.co.uk/2012/04/mono-for-android-portable-libraries-in.html)

  • Install a file called "MonoAndroid,Version=v1.6+.xml" in "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0\Profile\Profile104\SupportedFrameworks" with content:



  • Install a similar file called "VSMonoTouch,Version=v1.0+.xml" in the same directory and for its content use:

Note: the VSMonoTouch file is slightly hackier than the MonoDroid one - it points the portable tools at Full .Net v1.0 exactly as the VSMonoTouch plugin does - but I think this can cause some tool confusion sometimes.

After creating these xml files, then you should be able to use PCL projects of profile 104 across all platforms.

There are however some small additional problems you may need to solve at build time:

  1. If you share solutions back to the Mac, then MonoDevelop currently only likes Profile1 at Build time. To work around this, you may find you need to force Profile104 across to Profile1 using a conditional statement in your csproj file. Jon Pepper found this solution - thanks - http://slodge.blogspot.co.uk/2012/10/a-temporary-solution-for-profile1-only.html

    Note that this problem is marked as solved in bugzilla - see https://bugzilla.xamarin.com/show_bug.cgi?id=7173 - so this fix might be available in an alpha, beta or full release soon.
  2. If you share solutions back to the Mac,and if you have an older MonoDevelop installation, then you may also find that it fails to open .sln files. This bug has been around since May, but is almost fully fixed now. To workaround it you can manually change the .sln to say 11 rather than 12 - see https://bugzilla.xamarin.com/show_bug.cgi?id=4919
  3. To make use of some of the namespaces included in PCL you may need to setup shim assemblies to redirect DLL references. I've done this for System.Net, System.Windows and part of System.Xml.Serialization - see https://github.com/slodge/MvvmCross/tree/vnext/PortableSupport

    Note that these projects are quite simple - they just do type redirects from the full .Net assembly names to the Silverlight equivalents (Silverlight/MoonLight is where MonoTouch and MonoDroid started life)

    However, also note that there are some quirky things like public key signing and file renaming that we've had to do in order to get round some issues - see https://bugzilla.xamarin.com/show_bug.cgi?id=8035 and http://stackoverflow.com/questions/13028321/portable-class-library-strong-assembly-reference-problems-in-monotouch-monodroid

    I hope that these Shim assemblies become standard somewhere sometime soon - my versions are MS-PL and I would love to see someone (MS or Xam) take them and ship them more officially.

    For more on why Shim assemblies are needed see - http://stackoverflow.com/questions/10361457/is-it-possible-to-use-a-portable-class-library-that-references-system-net-in-mon

PCLs and Mono for Android


Using PCLs in Mono for Android inside VS2012 is very straight-forward.

You can easily reference Profile104 projects

You can easily reference Profile104 pre-built assemblies.

Sometimes you need to add the shim DLLs to add support for things like System.Net - but this is a solved problem - just reference the shims from the MvvmCross project and you are there.

However... there are two major problems with Mono for Android and PCLs right now - see https://bugzilla.xamarin.com/show_bug.cgi?id=8209:
  1. Sometimes you seem to need to build a solution twice to make it work
  2. You cannot debug (breakpoints, step into, etc) inside a PCL
Neither of these problems occurs currently in VS2010 using PCLs and Mono for Android - so maybe it is better to code there if you can.

PCLs and MonoTouch


Using PCLs in VSMonoTouch inside VS2012 is very straight-forward.

One word of warning - if you want to share PCLs at a binary level - then build these PCLs in the VisualStudio tools - not in MonoDevelop. This I think is because of code signing and reference assembly issues.

PCLs and Playstation Studio


I've briefly tried reusing PCLs with Playstation Studio/PSVita.

Project files wouldn't load in PSS

PCL assembly files could be referenced but I got serious errors at runtime - e.g. trying to use JSON.Net failed with horrible Type Exceptions. See http://stackoverflow.com/questions/10462462/using-portable-class-libaries-in-playstationstudio-projects


PCLs and Xamain.Mac


I've briefly tried reusing PCLs with MonoMac/Xamarin.Mac.

Project files would load in MonoDevelop, but I couldn't reference them across to MonoMac projects.

PCL assembly files could be referenced but in MonoMac projects, but I got errors at compile time - see http://forums.xamarin.com/discussion/599/portable-class-libraries-supported#latest

I have been informed that PCLs should definitely work in .Mac - so will try some more.

PCLs and Async/Await


This is not an area I've touched yet - I'm waiting for MonoTouch/Droid official async/await support - then I will work out how to add it into PCLs....

If you are interested, then here is what I know:

PCL v2 does not support async/await.
 
You can add async/await support to PCL v2 using a nuget package - http://nuget.org/packages/Microsoft.Bcl.Async

But this nuget package does not like the MonoDroid and VSMonoTouch additions. If you want to add the package then the advice is:
If you've modified your profile to support MonoTouch and MonoDroid, then a NuGet package typically won't install because the package doesn't list those platforms as supported.
The workaround is to quit VS, go to the profiles directory and rename the xml files you added, re-launch VS, and then reference the NuGet package
Daniel Plaisted did lots of work around this for his BUILD talk - http://channel9.msdn.com/Events/Build/2012/3-004 - the resources for this project include a working MonoDroid async/await sample.

Using nuget


nuget does now contain Portable Library support, but there are some limitations to extending this to monotouch and monodroid targets.

From v2.3 nuget will also contain some monodroid, monotouch and monomac support.

However, this support is very early days - I expect the tools will need some more work to make the experience really fly. I personally intend to invest some time in this - maybe in lobbying, but hopefully in coding (nuget is open source). If anyone wants to join this effort, please do.

I believe nuget when fully working across PCLs, MonoMac, Mono for Android and MonoTouch will be *amazing*


Is it worth the effort? Can't I just use file linking?


Yes, you can just use file linking.

Only you can decide if it's worth the effort.

A very good summary of the pro's and con's is in this Q&A - http://stackoverflow.com/questions/13797385/what-is-the-advantage-of-using-portable-class-libraries-instead-of-using-add-as

I personally love PCLs because they have definitely improved my speed of writing and refactoring code. I'm not claiming that progress is easy... but I am loving using them - so thanks to all in MS, in Xam and in the community (VSMonoTouch and beyond!) who are helping make these better. Indeed, much of the input from MS and Xam seems to have come while 'off duty' :)

The future


I've heard ongoing rumours that Xamarin may have a VS plugin for MonoTouch in development. I believe this was even demo'd live in early 2012... but maybe I was imagining it. Certainly Xamarin have some lovely new products lined up for 2013 - I'm hoping this is part of one of them.

Being able to build all of of PCL, WindowsStore, MonoDroid, MonoTouch, WP, WPF and MonoMac projects within one solution is already amazing today.

Making this support more official (without the VSMonoTouch and PCL reference hacking) and then adding full nuget support would be *fabulous* - I'm so looking forwards to doing single machine binary release and publishing.

Honestly I don't expect this future to arrive in the next month or three... so I do expect anyone who wants to build cross-platform solutions to need some patience and to do some considerable swearing... but the progress in the last year has been remarkable - and we are moving forwards.

MvvmCross today is a single solution containing 120 projects from 7 different project types - it builds, it supports refactoring and it offers me a really stable development environment.

I have gone through setup pain in the past, but this work means I can now spend my time coding - which makes me happy :)

Forwards!

8 comments:

  1. Try switching off Hyper-V by following this posts instructions.

    http://tom-dw.blogspot.nl/2011/08/vmware-on-hyper-v-machine.html

    ReplyDelete
    Replies
    1. Uhm, I mean for fixing the issues with the Android Emulator

      Delete
  2. to enable PCL-Support for the new Xamarin Studio try this:

    Xamarin.Android,Version=v1.6+.xml:



    Xamarin.iOS,Version=v4.0+.xml:

    ReplyDelete
  3. When I was building the Wpf libraries, I had the problem that I didn't have System.Windows.Interactivity on my machine. When I installed the Blend SDK for Silverlight 4 which is supposed to the DLL, it didn't complain about the code but gave me an error along the lines of

    "You must add a reference to assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes'."

    In the end I followed another StackOverflow post and used the 4.5 DLL that was included in this download:

    http://mvvmlight.codeplex.com/releases/71278/download/267119

    Possibly downloading a different version of the Blend SDK could have worked as well

    ReplyDelete
  4. Great post! This helped our team move towards a MVVM pattern using Mono. We are also using iFactr for views across platforms.

    Anyways, I figured I would share that I was able to get MonoTouch working a bit easier than the post says. It worked exactly as MonoDroid did. If anyone has any questions, let me know and I can elaborate.

    ReplyDelete
    Replies
    1. Thanks Brett. Yes - MonoTouch is a bit easier now... and hopefully will be even easier yet soon. Thanks for sharing. Would love to read any posts you have on how iFactr development is - I don't know the first thing about it!

      Delete
  5. I can comment on iFactr development. The premise of iFactr is cross-platform UI. In other words, your "views" contain all kinds of generic controls, menus, lists, etc. None of these are platform-specific UI elements, they're just abstract, represented using iFactr's API. These generic views (known as "layers" in iFactr lexicon) are navigated to via NavigationMappings (analogous to routes in ASP.NET MVC or Rails) and rendered by proprietary platform-specific factories that spit out views using the APIs of target platform. So, for example, there's a Touch factory, and an Android factory, and a Windows Phone factory, and a WPF factory, and a Compact Framework factory, etc, etc, etc. These platform-specific factories are part of iFactr's proprietary assemblies. So, iFactr gets you a long ways towards cross-platform UI. This of course presents certain constraints, however, in that the rendered UIs will closely resemble the UI guidelines of the target platform. In other words, UI customization is limited. iFactr also offers a cross-platform data stack for handling caching and queueing against RESTful endpoints. Beyond UI and data access, iFactr itself doesn't offer much to help the portability of the core abstract application; that's left to the developer. However, this is exactly why MonoCross emerged: to provide a framework for cross-platforming the core application. And from MonoCross, MvvmCross was born. So, in a way, MvvmCross is the grandchild of iFactr...although by way of some twists and turns. To be fair, I once worked on iFactr and developed apps with it. I am no longer using it, but it is still being actively developed and marketed.

    ReplyDelete
  6. Profile 104 doesn't work if you want to use 4.5 with Tasks as Silverlight 4 doesn't support Task. Any suggestion which profile will match the best in this case?

    ReplyDelete