Wednesday, August 21, 2013

Getting Started with Mobility, Part 5: Native Windows 8

In this series, we're introducing mobile development by looking at a variety of platforms. In Part 1, we provided an overview of the mobile landscape, and in Parts 2, 3, and 4 we examined native development for iOS, Android, and Windows Phone. Here in Part 5, we'll introduce you to native development Windows 8.

Windows 8: Microsoft's Platform for Tablets and PCs
Windows 8 is Microsoft's operating system for tablets that can also run on PCs. While Windows 8 is distinct from Windows Phone, as part of Microsoft's efforts to unify their products and services there are a number of similarities in terms of design principles and development skills.

Windows 8 apps are officially known as Windows Store Apps. Windows Store Apps can run on traditional Intel architecture machines (standard PCs, or the Surface Pro tablet) on Windows 8, Windows 8 Pro, or Windows 8 Enterprise; or, on ARM devices running Windows RT (such as the Surface RT tablet). On the former, you are able to run traditional Windows 7 apps as well as Windows Store apps; on the latter, only Windows Store apps.
Microsoft Surface Tablet

Windows 8 features a bold new look. The User Interface for Windows 8 was originally called Metro, but after objections from a company in Europe, Microsoft changed the name to Modern UI.

Windows 8 Start Screen
 
Windows 8 Weather App

The Computer You'll Develop on: A Windows PC or Surface Pro Tablet
Windows 8 development is done on a PC, or a compatible tablet like the Surface Pro. If you happen to use a Mac, you'll need to run a Windows VM in order to do Windows 8 development.

Developer Tools: Visual Studio and the Windows 8 SDK
For development, you'll need Visual Studio and the Windows 8 SDK. Although Visual Studio is a commercial product, there is a Visual Studio Express edition for Windows 8 available.

As we covered in Part 4, Visual Studio is a mature IDE familiar to anyone who develops for Microsoft's mobile, web, desktop, server, or cloud platforms.

Visual Studio IDE

Programming: WinJS, C#/XAML, or C++/XAML
For Windows Store app development, developers can choose from 3 lanes:
  • WinJS: HTML5, CSS, and JavaScript
  • C#/XAML: XAML screen markup and C# code-behind
  • C++/XAML: XAML screen markup and C++ code-behind
 
Windows 8 Platform
 
The choice of languages makes Windows 8 development very approachable to a broad number of developers. I'll give some attention to WinJS and C#/XAML here in this post, as they are the most frequently used.

It's important to note that all three of the approaches are first-class citizens and are all considered "native"--even when using HTML5/CSS/JavaScript. That's because all Windows Store Apps intrinsically leverage Internet Explorer--it's part of the platform and application model.

Programming in WinJS
Web developers will like being able to leverage HTML5, CSS, and JavaScript--including many of their preferred open source JavaScript libraries and frameworks. There are a few differences from standard web development however:
  • You don't have to worry about cross-domain "same origin" policy: a Windows Store app can reach out and access Internet URLs from anywhere. This is different from a web app, where you are restricted to your web server's originating domain.
  • Your code references need to be local. Including JavaScript or CSS from an online source is disallowed, so you'll need to copy those files locally into your project.
  • You can count on Internet Explorer being the browser, so you don't have to be concerned about supporting multiple browsers and testing whether specific browser features are available.
Here's what a view (page) looks like in WinJS:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>HelloWorld</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.2.0.Preview/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.2.0.Preview/js/base.js"></script>
    <script src="//Microsoft.WinJS.2.0.Preview/js/ui.js"></script>

    <!-- HelloWorld references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body>
    <h1>Hello, world!</h1>
    <p>What's your name?</p>
    <input id="nameInput" type="text" />
    <button id="helloButton">Say "Hello"</button>
    <div id="greetingOutput"></div>

</body>
</html>


And here's some code-behind JavaScript for that page:

// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/p/?linkid=232509
(function () {
    "use strict";

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll());

            // Retrieve the button and register our event handler.
            var helloButton = document.getElementById("helloButton");
            helloButton.addEventListener("click", buttonClickHandler, false);
        }
    };

    app.oncheckpoint = function (args) {
        // TODO: This application is about to be suspended. Save any state
        // that needs to persist across suspensions here. You might use the
        // WinJS.Application.sessionState object, which is automatically
        // saved and restored across suspension. If you need to complete an
        // asynchronous operation before your application is suspended, call
        // args.setPromise().
    };

    function buttonClickHandler(eventInfo) {

        var userName = document.getElementById("nameInput").value;
        var greetingString = "Hello, " + userName + "!";
        document.getElementById("greetingOutput").innerText = greetingString;
    }

    app.start();
})();


One of the things you'll notice from the above code is that you need to pay attention to application state. Like most mobile platforms, your apps can be suspended by the operating system and you'll need to ensure you save state and restore state appropriately.

Programming in C# and XAML
Silverlight, WPF, and Windows Phone developers will like being able to leverage familiar XAML and C#. Indeed, if you're developing for both Windows 8 and Windows Phone using C#/XAML makes a lot of sense as you'll be able to share some of your markup and code assets.

Here's an example of XAML screen markup for a Windows Store app:

<Page
    x:Name="pageRoot"
    x:Class="HelloWorld.MainPage"
    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloWorld"
    xmlns:common="using:HelloWorld.Common"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.Resources>
        <common:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
        <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
        <x:String x:Key="AppName">My Application</x:String>
    </Page.Resources>

    <!--
        This grid acts as a root panel for the page that defines two rows:
        * Row 0 contains the back button and page title
        * Row 1 contains the rest of the page layout
    -->
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ChildrenTransitions>
            <TransitionCollection>
                <EntranceThemeTransition/>
            </TransitionCollection>
        </Grid.ChildrenTransitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="140"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Back button and page title -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <AppBarButton x:Name="backButton" Icon="Back" Height="95" Margin="10,46,10,0"
                          Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
                          Visibility="{Binding IsEnabled, Converter={StaticResource BooleanToVisibilityConverter}, RelativeSource={RelativeSource Mode=Self}}"
                          AutomationProperties.Name="Back"
                          AutomationProperties.AutomationId="BackButton"
                          AutomationProperties.ItemType="Navigation Button"/>
            <TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1"
                       IsHitTestVisible="false" TextWrapping="NoWrap" VerticalAlignment="Bottom" Margin="0,0,30,40"/>
        </Grid>
    </Grid>
</Page>


And, here's an example of C# code to go with the XAML markup:

using HelloWorld.Common;
using System;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234237
namespace HelloWorld
{
    /// <summary>
    /// A basic page that provides characteristics common to most applications.
    /// </summary>
    public sealed partial class MainPage : Page
    {

        private NavigationHelper navigationHelper;
        private ObservableDictionary defaultViewModel = new ObservableDictionary();

        /// <summary>
        /// This can be changed to a strongly typed view model.
        /// </summary>
        public ObservableDictionary DefaultViewModel
        {
            get { return this.defaultViewModel; }
        }

        /// <summary>
        /// NavigationHelper is used on each page to aid in navigation and
        /// process lifetime management
        /// </summary>
        public NavigationHelper NavigationHelper
        {
            get { return this.navigationHelper; }
        }


        public MainPage()
        {
            this.InitializeComponent();
            this.navigationHelper = new NavigationHelper(this);
            this.navigationHelper.LoadState += navigationHelper_LoadState;
            this.navigationHelper.SaveState += navigationHelper_SaveState;
        }

        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="navigationParameter">The parameter value passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
        /// </param>
        /// <param name="pageState">A dictionary of state preserved by this page during an earlier
        /// session.  This will be null the first time a page is visited.</param>
        private void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
        {
        }

        /// <summary>
        /// Preserves state associated with this page in case the application is suspended or the
        /// page is discarded from the navigation cache.  Values must conform to the serialization
        /// requirements of <see cref="SuspensionManager.SessionState"/>.
        /// </summary>
        /// <param name="pageState">An empty dictionary to be populated with serializable state.</param>
        private void navigationHelper_SaveState(object sender, SaveStateEventArgs e)
        {
        }

        #region NavigationHelper registration
        /// The methods provided in this section are simply used to allow
        /// NavigationHelper to respond to the page's navigation methods.
        ///
        /// Page specific logic should be placed in event handlers for the 
        /// <see cref="GridCS.Common.NavigationHelper.LoadState"/>
        /// and <see cref="GridCS.Common.NavigationHelper.SaveState"/>.
        /// The navigation parameter is available in the LoadState method
        /// in addition to page state preserved during an earlier session.

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            navigationHelper.OnNavigatedTo(e);
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            navigationHelper.OnNavigatedFrom(e);
        }

        #endregion
    }
}


Online Resources
Like most mobile platforms, Microsoft provides a comprehensive developer center for Windows Store Apps. It includes design guidance, developer resources, training, code and tool downloads, community forums, and store management.

Windows Store Apps Developer Center

You'll want to check out these resources:
Get Started with Windows Store Apps
The Basics
App Architecture
Design Principles
How to Develop Windows Store Apps
API Reference
Sample Code
Community Forums

Tutorials
Microsoft provides a lot of online tutorial content, as well as periodic developer events in regional areas around the world. You might also consider Pluralsight video training courses, which have a lot of Windows 8 content.

1a. WinJS: Create your first Windows Store app using JavaScript

This tutorial walks you through creating a simple Hello, World app using HTML and JavaScript. The tutorial walks you through creating Hello World, then managing app lifecycle and state; working with page control objects and navigation; working with layout and orientation; and adding file picker functionality to select a photo.

Part 1 of Tutorial
 
Part 5 of Tutorial
 
1b. C#/XAML: Create your first Windows Store app using C#

This tutorial is similar to the Hello World app described above, but uses C# and XAML for development. This edition of the tutorial also includes creating a blog reader.

Part 4 of Tutorial

Part 5 of Tutorial

2a. WinJS: Developing Windows Store Apps with HTML5 Jumpstart

Microsoft Virtual Academy provides a video series on getting started with Windows Store app development in HTML5/JavaScript. Topics covered include:
  • Designing a Windows Store App
  • Developing Windows Store Apps
  • Working with Contracts
  • UI and Controls
  • Programming User Interactions
  • Data Access

2b. C#/XAML: Essentials of Developing Windows Store Apps using C# Jump Start

Microsoft Virtual Academy also provides a video series on getting started with Windows Store app development in C#/XAML. Topics covered include:
  • Overview of the Windows 8 Platform and Windows Store Apps
  • Creating User Interfaces using XAML
  • Presenting Data and Implementing Layout using Windows 8 Built-in Controls
  • Handling Files in Windows Store Apps and Process Lifecycle Management
  • Working with Resources, Styles, and Templates
  • Designing and Implementing Navigation in a Windows Store App
  • Implementing Windows 8 Contracts, Tiles and User Notifications
  • Local data and Planning for Windows Store App Deployment
  • Recommended Resources and Next Steps for Essentials of Development

Summary: Native Windows 8 Development
Windows 8 is a bit of a category-buster: it's Microsoft's chosen platform for tablets as well for PCs. Windows Store apps need to be designed to work well in a touch-centric environment, but should also support mouse and keyboard well. They need to support a variety of form factors. The three first-class language paths make Windows 8 app development accessible to web developers, C#/.NET developers, and C++ developers.

Next: Getting Started with Mobility, Part 6: Hybrid Development in C# with Xamarin

No comments: