Playing around with the Xamarin bits have had me pondering cross-platform .NET on the client side and that has led to me thinking about the approach Silverlight took to cross platform .NET clients.
NB: There’s a big history around browsers and plug-ins and so on which I’m not trying to get into here.
Instead, I’m thinking more about Silverlight’s role as the XAML/.NET engine for the Windows Phone apps platform and the broader approach that it took towards portable .NET client apps.
Cutting short all the history – by the time of version 5, Silverlight provides a platform which can be used to build different kinds of apps packaged up into a ZIP file and delivered either from the web, from an app store or simply installed from something like a USB key.
Those different kinds of apps span;
- The Desktop – across multiple versions of Windows and also specific OS X versions.
- The Browser – across multiple versions of multiple browsers on both Windows and OS X.
- Mobile Devices – for the Windows Phone delivered from the Windows Phone Store (Marketplace in the earlier days).
and the potential for .NET portability here is attractive – build an app for the Windows Phone in the same technology that could used to build an app for an OS X desktop app or an app to run in a Chrome browser on Windows XP.
That’s not though to suggest that you’d end up running the exact same app in all those places, you wouldn’t but the technologies would be the same.
Coming back to the “history” side of things – it’s also not to suggest that lots of folks are today building desktop apps or browser deployed apps in Silverlight.
Returning back to my “porting sandwich” diagram about portable code from a recent post;
Silverlight gives a developer quite a lot of consistency at all 3 levels on the right hand side of that diagram with some target-specific exceptions;
- e.g. the set of controls for the Phone differ somewhat from those for the browser/desktop although there’s quite a lot of commonality.
- e.g. there are some additional APIs on the Phone that don’t exist elsewhere.
- e.g. there are some additional APIs that you could use if the user installed an app to their desktop that you couldn’t use otherwise.
But those exceptions don’t cause a developer to have to introduce a whole new technology for the UI layer nor do they cause them to have to learn a whole new set of APIs at the “Platform API” layer.
Instead, there are some controls and/or platform APIs that only apply in certain situations and the developer makes use of them where they apply. It’s a matter of twisting and turning here and there rather than adopting something new and entirely different.
In terms of making use of Silverlight as a “mobile app” technology for Windows Phone, there’s a fairly natural fit in that Silverlight had been designed to deliver software from the web. It comes with the sorts of safe-guards that you need for a mobile app technology – i.e. easy install/uninstall, type-safety, security sandboxing and so on and is built on a fairly small framework and runtime which specifically target that purpose.
Silverlight works well as a mobile app technology which is a good thing given that it’s still, today, powering a lot of the 200,000+ applications in the Windows Phone Store.
That said, Windows Phone’s use of Silverlight as its application platform pre-dated the arrival of Windows 8 and the Windows Store and by that time, the landscape around Silverlight had changed such that it had primarily come to be used on the Windows Phone.
For a .NET developer though – the new XAML/.NET layer had a tonne of similarity with the Silverlight layers on the Phone and yet falls firmly into that category of “familiar, but different”. The technologies used to build a .NET Windows 8.1 app;
- C# programming language
- XAML UI language
- Set of UI controls
- Set of .NET Framework APIs
- Set of WinRT APIs
initially sound very similar to the ones used to build a Windows Phone 8.0 app but differences surface at levels other than with the C# programming language itself. The other layers all differ to a large enough extent to matter to a developer. Perhaps the most significant difference being that the platform APIs for Windows Phone 8.0 largely come from Silverlight whereas for Windows 8.1 they largely come from WinRT.
This means that trying to target both of the Windows/Phone platforms with common code needs work to loosely couple the 3 layers in the diagram above such that code in the middle can be abstracted from the dependencies that it has on the UX layer above it and the Platform API layer below it. There are strengths in the XAML/.NET platforms that make this easier than it might be in some other technologies – strengths like deep support for data-binding and an underlying support for runtime-type-introspection (or reflection). That loose coupling has benefits beyond those that it brings for code-portability including benefits in re-use, testability and perhaps maintainability as well.
As an example, if you have an app that calculates PI and displays the results then you will end up perhaps with something like this where I’m calling the Windows 8.1 variant of XAML “Windows/XAML” and the Windows Phone 8.0 variant of XAML “Silverlight/XAML”;
Assuming some simple UI, the XAML UI definitions might look very similar (but not identical) and because the logic makes no calls into the underlying platform, the implementation can almost certainly be built once and simply re-used (at the binary library level) across both applications. However, if the C# component wanted to do something more realistic such as make an HTTP request then that would be done in different ways on the two platforms;
and if the light blue component in the middle of the diagram was something that the developer wanted to share then it would need to be written to abstract itself from the different underlying implementations of doing HTTP work on the two platforms and hence the dotted lines in the diagram. That HTTP code then gets written twice.
It’s worth pointing out that this isn’t a brilliant example because there is a portable .NET version of the HttpClient class that can be used directly on both platforms but it’s an addition to the Windows Phone 8.0 platform rather than something that’s built in as it is in Windows 8.1 (in 2 variants). I’m using it here as an illustration of a broader set of differences rather than as a specific API that’s hard to work around.
Indulging my imagination for a moment – if Windows 8 had taken the approach that Windows Phone had taken and had expanded the Silverlight model for its app platform then this diagram might have looked more like this imaginary diagram below;
in which there are 2 UI’s to cater for the different requirements of a Windows app and a Phone app but the technology at the UI layer would have been the same and the underlying platform APIs might have been very similar and so a developer would not need to abstract out platform differences but could simply call a common API that surfaces in both places. There is more in common and so there’s less code to write (and test, and fix).
The ultimate extension of that fantasy would have been for the reach of Silverlight to expand out to include other mobile device platforms – i.e. iOS and Android. That might have been a big technical challenge in the sense of trying to figure out whether a truly cross-platform framework would attempt to somehow surface the native capabilities of each platform or go with more of a lowest-common-denominator style approach. No doubt, there would also have been big challenges beyond the technical.
But…that’s all just fantasy as those things didn’t happen although, of course, .NET code running on non-Microsoft platforms is very much a reality.
The position today for the developer looking to build common .NET code across Windows/Phone is the former picture (the one without the big “Made Up Platform” banner across it ).
For me, this is where Xamarin plays its role because those same techniques used for building across the differences in the Windows/Phone platforms can be married up with Xamarin’s technologies in order to do similar work for the iOS/Android platforms. Diagrammatically, that perhaps looks like;
with a developer looking to maximise the shared code in the central light blue box but accepting that 4 user interfaces need to be built in their native technologies and, where the shared code needs to call the platform, building 4 implementations of that functionality and placing those implementations behind some common abstraction.
The big benefit for a .NET developer is that they can take advantage of Xamarin to stay in C# and in Visual Studio while learning some new UI and API layers for Android/iOS. That’s a whole lot better than not being able to share code but I think it’d be great to see more convergence here across these platforms to reduce that work of building things multiple times.
For the Windows/Phone platforms it’d be great to see more commonality around the variants of XAML being used and also around the underlying APIs (i.e. Silverlight/WinRT). The Windows/Phone teams have stated that they are doing work around “convergence” and some initial steps (such as unifying the developer registration) have started to appear but there’s more to be done and, at the time of writing, it’s a “wait and see” with respect to how and when that work continues.
Beyond those “Windows” platforms, I’d probably have to accept that as a .NET/XAML developer it’s maybe a little unrealistic to expect to take a UI defined in XAML to Android/iOS and re-use it on those platforms so maybe that work around building multiple UIs in the native technologies is going to be there or at least for the foreseeable future and that idea lines up with each of those platforms having different UX.
But at the underlying platform API level I think it’d be great to see more convergence on those APIs. As examples, rather than have 4 sets of platform APIs to;
- display a toast notification
- store application settings
- store a file
perhaps there’s a broader approach that can be taken here – i.e. it feels to me that there’s a space for “someone” to fill by broadening out the abstractions across those multiple platforms so that the code in the blue box can grow and each individual app developer doesn’t have to build the abstractions and implementations for this kind of common functionality.
Of course, here I’m just musing – I don’t know who that “someone” might be. Maybe it’s something that the Xamarin might take on or maybe it’s something that lives with the community. Maybe it’s even something that Microsoft might take on in the future (not something I’ve ever heard suggested by the way) or maybe it’s the sterling work that a framework like MvvmCross is already doing in this area with abstractions already around things like Files, Resources, Sqlite, PhoneCalls, Json and so on.
I’m just guessing but I definitely think that there’s room for improvement here and it’ll be interesting to see where this goes in the future…
As an aside, while I was writing this post the always-excellent David Chappell write “A Perspective on Xamarin” which is a great read and touches on some topics similar to those in this post.