Mobile Corner

Building Apps Across Windows 8 Platforms

Although Windows 8 and Windows Phone share the same core, building an app for both isn't as easy as you might think.

Windows 8 and Windows Phone 8 are finally here. In this article, I'll look at key similarities and differences between developing applications for these two new platforms.

I'll start by taking a look at what it means to build for a Windows device. With the rapid adoption of touch-based computing, there's a need for traditional forms-based interfaces to evolve, making them more touch-friendly.

Don't Start Me Up
One such transition is the rather dramatic departure from a Start button, arriving at an entire Start screen. Those already familiar with Windows Phone will recognize the Live Tile concept and immediately feel at home. Live Tiles are not simply application shortcuts; they're about displaying a snapshot or status of each application, or part of an application.

The immediate question that developers ask is whether it's possible to build a single application that works across both Windows and Windows Phone. In theory, this sounds like a great idea, but the reality is that, when executed, it leads to an awful experience.

Take, for example, what happens if you run an iPhone version of an application on an iPad. Despite the ability to magnify it to fill the screen, the experience isn't anything like an application specifically designed for an iPad. Currently, there are three resolutions developers have to target for Windows Phone. This means applications can be heavily optimized for these resolutions without having to worry about how the app scales to different form factors.

Windows 8, by comparison, does have to cater to varying screen sizes, from the smallest screens (1024x768) to much larger screens (no upper limit). This in itself can be a daunting task. Luckily, a number of the controls available in the SDK lend themselves well to building scalable applications.

Both Windows 8 and Windows Phone have multiple orientations that developers can choose to handle within their application. For Windows Phone, support for different device orientations can be handled at a page level. It's entirely opt-in, with portrait being the default for most applications.

Windows 8 applications, on the other hand, can opt out of supporting certain orientations at an application level, with landscape being the default for most applications. But they're also required to support Snapped mode, where the application is docked to one edge of the screen. It's important to note that dealing with orientations alone will increase the complexity of development and testing of a Windows 8 application, compared to a Windows Phone application.

Choosing a Language
Applications for Windows Phone are written natively in C++. Managed applications are written with Silverlight for Windows Phone (for instance, XAML + C# or Visual Basic .NET), or with an HTML-wrapper technology such as PhoneGap for HTML/JavaScript/CSS-style applications. Windows 8, re-architected from the ground up, allows you to write apps using C++, C#/Visual Basic .NET or HTML/JavaScript/CSS. If you're looking to maintain a compatible code base across both platforms, you'll probably want to go down the XAML + C#/Visual Basic .NET path.

Silverlight and Windows Presentation Foundation (WPF) developers will be familiar with the separation of design (XAML) from the code (C#/Visual Basic .NET). There are some subtle inconsistencies between the XAML used by Windows Phone and Windows 8 that will prevent you from using the same XAML across both applications.

In addition to considering how the individual screens are laid out, you also need to consider the navigation path and interaction model throughout the application. Windows Phone incorporates a hardware back button, making it easy for users to back out of the current screen. There's no such requirement for Windows applications, which means that if you're not careful, the user might get lost.

Lifecycle Considerations
You also need to consider the different entry points and the overall lifecycle of the application. When building a Windows Phone application, you must consider the effects of tombstoning, where your application might need to resume from a not-running state. This isn't the case with Windows 8 applications, although you do still need to deal with suspended states. Both platforms support being entered via a push notification, but Windows 8 also allows entry via the Search or Share charms.

There's an argument to be made for creating a Windows 8/Windows Phone 8 app that can reuse a single codebase, but this isn't as easy as it sounds, due partially to historical reasons. Windows Phone is an almost direct derivative of Silverlight for the desktop. Windows 8 has been re-engineered as a better, quicker and more reliable platform (for example, asynchronous operations have been used for operations that can block or take a finite amount of time to execute).

Although there's an overlap of commonalities between the platforms, the incompatibilities range from simple namespace changes to big differences in the way certain operations are performed. If you want to build one application that works on both platforms, I'll present four ways to architect your code that maximize the reuse between your apps.

Reuse Strategy No. 1: Portable Class Libraries
The concept of a portable class library (PCL) stems from the fact that both platforms intersect over a large set of common types. If your code -- and other libraries it might rely on -- only uses this subset of the Microsoft .NET Framework, you can generate a PCL that can simply be referenced by both Windows 8 and Windows Phone applications.

When working with a PCL, you might notice limitations imposed by the need to work across multiple platforms. For instance, there's a lack of support for Tasks, which impacts the async/await keywords. A workaround for this is to add the Microsoft.Bcl.Async NuGet package.

Reuse Strategy No. 2: Conditional Code Blocks
The next three alternatives involve including the code files in both Windows 8 and Windows Phone projects. As such, they're not mutually exclusive; it's a matter of selecting the best or most appropriate technique for your scenario.

The first is to use conditional code blocks to effectively hide parts of the code file, based on the platform for which it's being compiled. By default, Windows Phone applications define WINDOWS_PHONE, and Windows 8 applications define NETFX_CORE. For example, the following code includes a different namespace, depending on which platform it's being built for:

#if NETFX_CORE
  using Windows.UI.Xaml.Media.Imaging;
#else
  using System.Windows.Media.Imaging;
#endif

While this appears to be relatively simple to follow, it quickly becomes unmanageable if used for large blocks of code. It's hard to identify which code is platform-specific versus common code.

Reuse Strategy No. 3: Inheritance
One option for making it easier to separate common code from platform-specific code is the use of inheritance. With this model, the common code would reside in the base class, with platform-specific code being added to a sub-class.

The code in the sub-class can belong to two cases: The first is where additional functionality has been added for a particular platform (for instance, sending an SMS on Windows Phone). The second is where a function needs to be implemented in a platform-specific manner (for example, file access). In the second case, it might be that the base class defines an abstract method, requiring its completion in the sub-class, like this:

public abstract class MainPageViewModel : NotifyBase,IViewModel
{
  protected abstract void DisplayPicture();
}

public class WinMainPageViewModel : MainPageViewModel, 
  ISupportsDesignTimeDataViaCode
{
  protected override void DisplayPicture()
  {
    // Implementation to display picture on Windows
  }
}

Reuse Strategy No. 4: Partial Classes and Methods
An alternative to using inheritance is to use partial classes and methods. Partial classes were originally introduced to allow developers to add supplementary code to classes that had been generated (either by a designer or some other code generator). By placing the code in a separate file, it wasn't overwritten the next time the code generator was run.

This same technique can be used to separate out common code and platform-specific code, as in this example where the LoadFolders method is implemented in a separate file:

public partial class DataSource:IDataSource {
  public async Task <IEnumerable <IFolder > > RetrieveFolders(IFolder root) {
    ... // Other logic
    var folders = await LoadFolders(root);
    ... // Other logic
    return folders
  }
}

public partial class DataSource {
  private async Task <IEnumerable <IFolder > > LoadFolders(IFolder root) {
    ...
  }
}

There's also the concept of partial methods. In this, the method signature can be defined alongside the common code, and the implementation can reside in a different file. However, there are restrictions on the method signature, such as having a void return type, which can make it ineffective for the purposes of separating out platform-specific code.

When you're trying to work out which of these reuse patterns to use, it's helpful to look at the APIs exposed by the different platforms. Some, such as the accelerometer, have an API that's almost identical; others are significantly different and can impact the way you structure your code (for example, the camera capture task for Windows Phone applications).

Data Binding
It's worth revisiting the way data binding works across both platforms. A common pattern used across Silverlight, WPF, Windows Phone and now Windows 8 is Model-View-ViewModel (MVVM). At its root, MVVM is all about data binding and how you can separate the data and logic from the way the data's rendered.

As you think through how you're going to reuse code between the two platforms, you should be focusing on how much of the model and view model you can reuse. As mentioned earlier, the view will -- and should -- be different between the two platforms. By reusing the model and view model, you'll end up with both a high level of reuse and a similar application structure and navigation model.

It Gets Easier
In this article I've touched on some of the similarities and differences between the Windows 8 and Windows Phone 8 platforms. The similarities will grow because both platforms share a common core, and over time we can expect it to become even easier to build applications that target both platforms.

About the Author

Nick Randolph runs Built to Roam, a consulting company that specializes in training, mentoring and assisting other companies build mobile applications. With a heritage in rich client applications for both the desktop and a variety of mobile platforms, Nick currently presents, writes and educates on the Windows Phone platform.

comments powered by Disqus

Featured

  • Compare New GitHub Copilot Free Plan for Visual Studio/VS Code to Paid Plans

    The free plan restricts the number of completions, chat requests and access to AI models, being suitable for occasional users and small projects.

  • Diving Deep into .NET MAUI

    Ever since someone figured out that fiddling bits results in source code, developers have sought one codebase for all types of apps on all platforms, with Microsoft's latest attempt to further that effort being .NET MAUI.

  • Copilot AI Boosts Abound in New VS Code v1.96

    Microsoft improved on its new "Copilot Edit" functionality in the latest release of Visual Studio Code, v1.96, its open-source based code editor that has become the most popular in the world according to many surveys.

  • AdaBoost Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the AdaBoost.R2 algorithm for regression problems (where the goal is to predict a single numeric value). The implementation follows the original source research paper closely, so you can use it as a guide for customization for specific scenarios.

  • Versioning and Documenting ASP.NET Core Services

    Building an API with ASP.NET Core is only half the job. If your API is going to live more than one release cycle, you're going to need to version it. If you have other people building clients for it, you're going to need to document it.

Subscribe on YouTube