Now that the Build 2014 conference is over and the dust begins to settle, it’s time to look at what we’ve got. And there’s plenty to look at. In this post I’d like to take a closer look at Universal apps, their structure and possible future.
Before these so-called “universal” apps, creating apps for Windows 8.x Store and Windows Phone 8 was mostly a two-app project. Sure, some logic code could be shared via Portable Class Libraries (PCL), but the common surface of PCLs was too small, leading to many #if/#endif statements. Also, sharing XAML was extremely difficult, and in my experience a futile exercise, so it had better be kept separate.
Other stuff, similar on the outside, such as live tiles and push notifications, had to be done differently, because it was a different API, built on different foundations. Windows Store was built on top of the Windows Runtime (WinRT) – a native, COM based API, while the Windows Phone API was mostly Silverlight-based – pure .NET mostly. Yes, with the 8.0 version of Windows Phone some WinRT APIs made it to the phone (WinPRT), common with WinRT, but that common API was relatively small.
With Windows Phone 8.1 and Windows 8.1 Update, things are changing, or should I say – converging. The WinRT API has spread to the phone, replacing “legacy” Silverlight based APIs. For example, the Windows.UI.Xaml.Controls.Button class from WinRT now exists as a Win(P)RT type in WP 8.1. The “old” button, System.Windows.Controls.Button is still there to support existing apps, but it looks like the future is WinRT, and not Silverlight.
Another effect of this convergence is the “Universal PCLs”, which are now expanded to include a much larger surface area than non-universal PCLs. “Non-universal” here really means PCLs that target more than Windows 8.1 and Windows Phone 8.1.
Universal Apps are there to allow the same app to be written for Windows 8.1 Store and Windows Phone 8.1 with little code changes. Almost everything can be shared, and obviously some things will have to change, such as UI layout, or usage of special features of one platform or the other. But, as it turns out, most code, and even XAML can actually be shared; and that’s a real advantage we didn’t have before.
Let’s create a simple Universal App and examine its components. To get support for this, you’ll need Visual Studio 2013 (any SKU) with Update 2 (RC at the time of writing). This will install the proper project templates and other required support to get this working.
From Visual Studio, select File -> New Project and navigate to the new Store Apps subfolder:
It’s actually possible to start with a Windows 8.1 app or a Windows Phone 8.1 App and add its “twin” app using a context menu option on the project node in solution explorer.
With the Universal App selection, we get two app projects, one for Win 8.1 and the other for Win Phone 8.1. The unusual part is the third, “Shared” project:
Notice the projects look very similar. The Silverlight manifest file WMAppManifest.xml has been transformed into Package.appxmanifest, essentially the same as its Windows 8.1 counterpart.
As we can see, the “Shared” project has App.xaml and App.xaml.cs shared by default. This means these files do not appear in the normal projects, but are “pulled” by each one when built.
The Shared project is a bit weird, as it has no output on its own – it’s not a DLL, EXE, XAP or whatever. It’s nothing; it just contains shared stuff that must be pulled by each of the “real” projects. It doesn’t even have a References node.
So what happens if we want to use some class library (it better be a Universal PCL)? We add it as a reference for each of the real projects, and then its contents is available for use in the Shared project. Get it?
Let’s do some experimentation. Drag the MainPage.xaml file from the Windows Phone project to the Shared project’s node:
Notice the file does not disappear from the original project. Trying to build now yields 2 errors, because there are 2 files with the same name (identity) for each project.
Let’s delete the MainPage.xaml file (along with its code behind) from the Win 8.1 and WP 8.1 projects, leaving it in the Shared project only:
Now the two projects build just fine, and they even run perfectly fine. In this case, the MainPage.xaml file was identical in the original two projects, so no harm, no foul. Let’s add a simple Button control to the Grid that exists in that (now single) MainPage.xaml:
<Button Content=”Click me!” FontSize=”40″ HorizontalAlignment=”Center”/>
The designer now has an option to switch to one of two views – Win 8.1 or Win Phone 8.1 so we can check out the results at design time:
Running each app shows the button as we expect, in the Grid’s center.
By the way, notice that the XAML has converged, so that Windows Phone and Windows 8 now recognize the same syntax, such as the way to map a XAML namespace to a CLR namespace using the “using” keyword rather than the “clr-namespace” keyword, as was done with the “Silverlight way”. This is just one aspect that makes sharing XAML possible.
Of course, for XAML things are never that easy, as a Win 8.1 page may be very different from a phone page, but with the help of user controls that can be shared, even non-shared pages become relatively easy to maintain.
Clearly, there’s still a way to go, but I believe this is a good direction. What is apparent is that WinRT is the present and future, but the Silverlight API is just there for compatibility and maintenance. So, if you’ve been avoiding or neglecting WinRT – don’t. New apps (even if they are not planned to be multi-platform) should be based on the WinRT API and not the Silverlight one.
From my perspective the only thing missing in this story is the Desktop. Microsoft realized, perhaps a year or a bit more ago that the desktop is not going away and is important as ever, if not more. Many apps run in the desktop (vs. Store), many apps rely on mouse and keyboard for their utilization, and touch is not the answer to everything.
I see no reason why the WinRT model, including the UI and XAML does not bleed into desktop apps as well. WinRT is just COM, after all, and in fact, many types can already be used in desktop apps. For some reason, XAML based UI still can’t but I believe it will. .NET developers have WPF, but native desktop developers have just MFC, which is outdated and primitive by comparison to either WPF or WinRT.
Sure, there are other C++ UI non-Microsoft alternatives, such as Qt, wxWidegts and many others, but that’s not enough. Microsoft should provide its own framework, and indeed it’s already here – that’s WinRT. It just needs to be “allowed” to execute in desktop apps.
In fact, I sense that WinRT is not just about “apps”; instead, it’s the new Win32 API. Every developer that’s familiar to some extent with the Win32 API understands these words. This API is old, mostly thousands of C-style functions, is unwieldy, and frankly only “old” guys use it, because it’s so difficult to learn given the alternative APIs. WinRT is for the most part well designed, object oriented, and is still native, so it has a lot going for it. It could very well be the new Windows API.