Chapter 2
Quickstart

This is a book about developing apps. So, to quote Paul Bettany’s portrayal of Geoffrey Chaucer in A Knight’s Tale, “without further gilding the lily, and with no more ado,” let’s create some!

A Really Quick Quickstart: The Blank App Template

We must begin, of course, by paying due homage to the quintessential “Hello World” app, which we can achieve without actually writing any code at all. We simply need to create a new app from a template in Visual Studio:

1. Run Visual Studio Express. If this is your first time, you’ll be prompted to obtain a developer license. Do this, because you can’t go any further without it!

2. Click New Project… in the Visual Studio window, or use the File > New Project menu command.

3. In the dialog that appears (Figure 2-1), make sure you select JavaScript under Templates on the left side, and then select Blank Application in the middle. Give it a name (HelloWorld will do), a folder, and click OK.

Image

FIGURE 2-1 Visual Studio’s New Project dialog using the light UI theme. (See the Tools > Options menu command, and then change the theme in the Environment/General section). I use the light theme in this book because it looks best against a white page background.

4. After Visual Studio churns for a bit to create the project, click the Start Debugging button (or press F5, or select the Debug > Start Debugging menu command). Assuming your installation is good, you should see something like Figure 2-2 on your screen.

Image

FIGURE 2-2 The only vaguely interesting portion of the Hello World app’s display. The message is at least a better invitation to write more code than the standard first-app greeting!

By default, Visual Studio starts the debugger in local machine mode, which runs the app full screen on your present system. This has the unfortunate result of hiding the debugger unless you’re on a multimonitor system, in which case you can run Visual Studio on one monitor and your Windows Store app on the other. Very handy. See Running apps on the local machine for more on this.

Visual Studio offers two other debugging modes available from the drop-down list on the toolbar (Figure 2-3) or the Debug/[Appname] Properties menu command (Figure 2-4):

Image

FIGURE 2-3 Visual Studio’s debugging options on the toolbar.

Image

FIGURE 2-4 Visual Studio’s debugging options in the app properties dialog.

The Remote Machine option allows you to run the app on a separate device, which is absolutely essential for working with devices that can’t run desktop apps at all, such as ARM devices (and if you see only this option with a sample project, the build target is probably set to ARM). Setting this up is a straightforward process: see Running apps on a remote machine, and I do recommend that you get familiar with it. Also, when you don’t have a project loaded in Visual Studio, the Debug menu offers the Attach To Process command, which allows you to debug an already-running app. See How to start a debugging session (JavaScript).

The Simulator is also very interesting, really the most interesting option in my mind and a place I imagine you’ll be spending plenty of time. It duplicates your environment inside a new login session and allows you to control device orientation, set various screen resolutions and scaling factors, simulate touch events, and control the data returned by geolocation APIs. Figure 2-5 shows Hello World in the simulator with the additional controls labeled. We’ll see more of the simulator as we go along, though you may also want to peruse the Running apps in the simulator topic.

Image

FIGURE 2-5 Hello World running in the simulator, with added labels on the right for the simulator controls. Truly, the “Blank App” template lives up to its name!

Under the covers, Visual Studio is actually deploying the app similar to what would happen if you acquired it from the Store. The app will show up on the Start page, where you can also uninstall it. Uninstalling will clear out appdata folders and other state, which is very helpful when debugging.

There’s really no magic involved: deployment can actually be done through the command line. To see the details, use the Store/Create App Package in Visual Studio, select No for a Store upload, and you’ll see a dialog in which you can save your package wherever you want. In that folder you’ll then find an appx package, a security certificate, and a batch file called Add-AppxDevPackage. That batch file contains PowerShell scripts that will deploy the app along with its dependencies.

These same files are also what you can share with other developers who have a developer license, allowing them to side-load your app without needing your full source project.

Blank App Project Structure

While an app created with the Blank template doesn’t have much in the visual department, it provides much more where project structure is concerned. Here’s what you’ll find coming from the template, which is found in Visual Studio’s Solution Explorer (as shown in Figure 2-6):

In the project root folder:

default.html The starting page for the app.

<Appname>_TemporaryKey.pfx A temporary signature created on first run.

package.appmanifest The manifest. Opening this file will show Visual Studio’s manifest editor (shown later in this chapter). I encourage you to browse around in this UI for a few minutes to familiarize yourself with what’s all here. For example, you’ll see references to the images noted below, a checkmark on the Internet (Client) capability, default.html selected as the start page, and all the places where you control different aspects of your app. We’ll be seeing these throughout this book; for a complete reference, see the App packages and deployment and Using the manifest designer topics. And if you want to explore the manifest XML directly, right-click this file and select View Code.

The css folder contains a default.css file where you’ll see media query structures for the four view states that all apps should honor. We’ll see this in action in the next section, and I’ll discuss all the details in Chapter 6, “Layout.”

The images folder contains four reference images, and unless you want to look like a real doofus developer, you’ll always want to customize these before sending your app to the Store (and you’ll want to provide scaled versions too, as we’ll see in Chapter 3, “App Anatomy and Page Navigation”):

logo.png A default 150x150 (100% scale) image for the Start page.

smalllogo.png A 30x30 image for the zoomed-out Start page and other places at run time.

splashscreen.png A 620x300 image that will be shown while the app is loading.

storelogo.png A 50x50 image that will be shown for the app in the Windows Store. This needs to be part of an app package but is not used within Windows at run time.

The js folder contains a simple default.js.

The References folder points to CSS and JS files for the WinJS library. You can open any of these to see how WinJS itself is implemented. (Note: if you want to search within these files, you must open and search only within the specific file. These are not included in solution-wide or project-wide searches.)

Image

FIGURE 2-6 A Blank app project fully expanded in Solution Explorer.

As you would expect, there’s not much app-specific code for this type of project. For example, the HTML has only a single paragraph element in the body, the one you can replace with “Hello World” if you’re really not feeling complete without doing so. What’s more important at present are the references to the WinJS components: a core stylesheet (ui-dark.css or ui-light.css), base.js, and ui.js:

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

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

    <!-- HelloWorld references -->
    <link href="/css/default.css" rel="stylesheet">
    <script src="/js/default.js"></script>
</head>
<body>
    <p>Content goes here</p>
</body>
</html>

You will generally always have these references (perhaps using ui-light.css instead) in every HTML file of your project. The //’s in the WinJS paths refer to shared libraries rather than files in your app package, whereas a single / refers to the root of your package. Beyond that, everything else is standard HTML5, so feel free to play around with adding some additional HTML of your own and see the effects.

Where the JavaScript is concerned, default.js just contains the basic WinJS activation code centered on the WinJS.Application.onactivated event along with a stub for an event called WinJS.Application.oncheckpoint:

(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());
        }
    };

    app.oncheckpoint = function (args) {
    };

    app.start();
})();

We’ll come back to checkpoint in Chapter 3. For now, remember from Chapter 1, “The Life Story of a Windows Store App,” that an app can be activated in many ways. These are indicated in the args.-detail.kind property whose values come from the Windows.ApplicationModel.Activation.-ActivationKind enumeration.

When an app is launched directly from its tile on the Start screen (or in the debugger as we’ve been doing), the kind is just launch. As we’ll see later on, other values tell us when an app is activated to service requests like the search or share contracts, file-type associations, file pickers, protocols, and more. For the launch kind, another bit of information from the Windows.ApplicationMode.-Activation.ApplicationExecutionState enumeration tells the app how it was last running. Again, we’ll see more on this in Chapter 3, so the comments in the default code above should satisfy your curiosity for the time being.

Now, what is that args.setPromise(WinJS.UI.processAll()) for? As we’ll see many times, WinJS.UI.processAll instantiates any WinJS controls that are declared in HTML—that is, any element (commonly a div or span) that contains a data-win-control attribute whose value is the name of a constructor function. Of course, the Blank app template doesn’t include any such controls, but because just about every app based on this template will, it makes sense to include it by default.7 As for args.setPromise, that’s employing something called a deferral that we’ll defer to Chapter 3.

As short as it is, that little app.start(); at the bottom is also a very important piece. It makes sure that various events that were queued during startup get processed. We’ll again see the details in Chapter 3.

Finally, you may be asking, “What on earth is all that ceremonial (function () { … })(); business about?” It’s just a conventional way in JavaScript (called the module pattern) to keep the global namespace from becoming polluted, thereby propitiating the performance gods. The syntax defines an anonymous function that’s immediately executed, which creates a function scope for everything inside it. So variables like app along with all the function names are accessible throughout the module but don’t appear in the global namespace.8

You can still introduce variables into the global namespace, of course, and to keep it all organized, WinJS offers a means to define your own namespaces and classes (see WinJS.Namespace.define and WinJS.Class.define), again helping to minimize additions to the global namespace.

Now that we’ve seen the basic structure of an app, let’s build something more functional and get a taste of the WinRT APIs and a few other platform features.

Get familiar with Visual Studio If you’re new to Visual Studio, the tool can be somewhat daunting at first because it supports many features, even in the Express edition. For a quick roughly 10-minute introduction, I’ve put together Video 2-1 in this chapter’s companion content to show you the basic workflows and other essentials.

Because of the dynamic nature of JavaScript, it’s impressive that the Visual Studio team figured out how to make the IntelliSense feature work quite well in the Visual Studio editor. (If you’re unfamiliar with IntelliSense, it’s the productivity service that provides auto-completion for code as well as popping up API reference material directly inline; learn more at JavaScript IntelliSense). That said, a helpful trick to make IntelliSense work even better is to write code while Visual Studio is in debug mode. That is, set a breakpoint at an appropriate place in your code, and then run the app in the debugger. When you hit that breakpoint, you can then start writing and editing code, and because the script context is fully loaded, IntelliSense will be working against instantiated variables and not just what it can derive from the source code by itself. You can also use Visual Studio’s Immediate pane to execute code directly to see the results. (You will need to restart the app, however, to execute that new code in place.)

QuickStart #1: Here My Am! and an Introduction to Blend for Visual Studio

When my son was three years old, he never—despite the fact that he was born to two engineers parents and two engineer grandfathers—peeked around corners or appeared in a room saying “Hello world!” No, his particular phrase was “Here my am!” Using that particular variation of announcing oneself to the universe, this next app can capture an image from a camera, locate your position on a map, and share that information through the Windows 8 Share charm. Does this sound complicated? Fortunately, the WinRT APIs actually make it quite straightforward!

This app took me about three hours to write. “Oh sure,” you’re thinking, “you’ve already written a bunch of apps, so it was easy for you!” Well, yes and no. For one thing, I also wrote this part of the chapter at the same time, and endeavored to make some reusable code. But more importantly, it took a short amount of time because I learned how to use my tools—especially Blend—and I knew where I could find code that already did most of what I wanted, namely all the Windows SDK samples that you can download from http://code.msdn.microsoft.com/windowsapps/.

As we’ll be drawing from many of these most excellent samples in this book, I encourage you to download the whole set—go to the URL above, and locate the link for “Windows 8 app samples”. This link will take you to a page where you can get a .zip file with all the JavaScript samples. Once you unzip these, get into the habit of searching that folder for any API or feature you’re interested in. For example, the code I use below to implement camera capture and sourcing data via share came directly from a couple of samples. (Again, if you open a sample that seems to support only the Remote Machine debugging option, the build target is probably set to ARM—change it to Any CPU for local debugging.)

I also strongly encourage you to spend a half-day, even a full day, getting familiar with Visual Studio and Blend for Visual Studio and just perusing through the samples so that you know what’s there. Such small investments will pay huge productivity dividends even in the short term!

Design Wireframes

Before we start on the code, let’s first look at design wireframes for this app. Oooh…design? Yes! Perhaps for the first time in the history of Windows, there’s a real design philosophy to apply to apps. In the past, with desktop apps, it’s been more of an “anything goes” scene. There were some UI guidelines, sure, but developers could generally get away with making up whatever user experience that made sense to them, like burying essential checkbox options four levels deep in a series of modal dialog boxes. Yes, this kind of stuff does make sense to certain kinds of developers; whether it makes sense to anyone else is highly questionable!

If you’ve ever pretended or contemplated pretending to be a designer, now is the time to surrender that hat to someone with real training or set development aside for a year or two and invest in that training yourself. Simply said, design matters for Windows Store apps, and it will make the difference between apps that succeed and apps that merely exist in the Windows Store and are largely ignored. And having a design in hand will just make it easier to implement because you won’t have to make those decisions when you’re writing code! (If you still intend on filling designer shoes and communing with apps like Adobe Illustrator, be sure to visit Designing UX for apps for the philosophy and details of Windows Store app design, plus design resources.)

When I had the idea for this app, I drew up simple wireframes, let a few designers laugh at me behind my back (and offer adjustments), and landed on layouts for the full screen, portrait, snap, and fill view states as shown in Figure 2-7 and Figure 2-8.

Note Traditional wireframes are great to show a static view of the app, but in the “fast and fluid” environment of Windows 8, the dynamic aspects of an app—animations and movement—are also very important. Great app design includes consideration of not just where content is placed but how and when it gets there in response to which user actions. Chapter 11, “Purposeful Animations,” discusses the different built-in animations that you can use for this purpose.

Image

FIGURE 2-7 Full-screen landscape and filled (landscape) wireframe. These view states typically use the same wireframe (the same margins), with the proportional parts of the grid simply becoming smaller with the reduced width.

Image

FIGURE 2-8 Snapped wireframe (left; landscape only) and full-screen portrait wireframe (right); these are not to scale.

Just as I thought about all four view states together for Here My Am!, I encourage you to do the same for one simple reason: your app will be put into every view state whether you design for it or not. Users, not the app, control the view states, so if you neglect to design for any given state, your app will probably look hideous in that state. You can, as we’ll see in Chapter 6, lock the landscape/portrait orientation for your app if you want, but that’s meant to enhance an app’s experience rather than being an excuse for indolence. So in the end, unless you have a very specific reason not to, every page in your app needs to anticipate all four view states.

This might sound like a burden, but view states don’t affect function: they are simply different views of the same information. Remember that changing the view state never changes the mode of the app. Handling the view states, therefore, is primarily a matter of which elements are visible and how those elements are laid out on the page. It doesn’t have to be any more complicated than that, and for apps written in HTML and JavaScript the work can mostly, if not entirely, be handled through CSS media queries.

One of the important aspects of Windows Store app design is understanding the layout silhouette: the size of the header fonts, their placement, the specific margins, grid layout, and all that (as marked in the previous figures). These recommendations encourage a high degree of consistency between apps so that users’ eyes literally develop muscle memory for common elements of the UI. Some of this can be found in Understanding the Windows 8 silhouette and is otherwise incorporated into the templates along with many other design aspects. It’s one reason why Microsoft generally recommends starting new apps with a template and going from there. What I show in the wireframes above reflects the layouts provided by one of the more complex templates. At the same time, the silhouette is a starting point and not a requirement—apps can and do depart from it when it makes sense. Absent a clear design, however, it’s best to stay with it.

Enough said! Let’s just assume that we have a great design to work from and our designers are off sipping cappuccino, satisfied with a job well done. Our job is how to then execute on that great design.

Create the Markup

For the purposes of markup, layout, and styling, one of the most powerful tools you can add to your arsenal is Blend for Visual Studio. As you may know, Blend has been available (at a high price) to designers and developers working with XAML (the presentation framework that is used by apps written in C#, Visual Basic, and C++). Now Blend is free and also supports HTML, CSS, and JavaScript. I emphasize that latter point because it doesn’t just load markup and styles: it loads and executes your code, right in the “Artboard” (the design surface), because that code so often affects the DOM, styling, and so forth. Then there’s Interactive Mode…but I’m getting ahead of myself!

Blend and Visual Studio are very much two sides of a coin: they share the same project file formats and have commands to easily switch between them, depending on whether you’re focusing on design or development. To demonstrate that, let’s actually start building Here My Am! in Blend. As we did before with Visual Studio, launch Blend, select New Project…, and select the Blank App template. This will create the same project structure as before. (Note: Video 2-2 shows all these steps together.)

Following the practice of writing pure markup in HTML—with no styling and no code, and even leaving off a few classes we’ll need for styling—let’s drop the following markup into the body element of default.html (replacing the one line of <p>Content goes here</p>):

<div id="mainContent">
    <header aria-label="Header content" role="banner">
        <h1 class="titlearea win-type-ellipsis">
            <span class="pagetitle">Here My Am!</span>
        </h1>
    </header>
    <section aria-label="Main content" role="main">
        <div id="photoSection" aria-label="Photo section">
            <h2 class="group-title" role="heading">Photo</h2>
            <img id="photo" src="images/taphere.png"
                alt="Tap to capture image from camera" role="img" />
        </div>
        <div id="locationSection" aria-label="Location section">
            <h2 class="group-title" role="heading">Location</h2>
            <iframe id="map" src="ms-appx-web:///html/map.html" aria-label="Map"></iframe>
        </div>
    </section>
</div>

Here we see the five elements in the wireframe: a main header, two subheaders, a space for a photo (defaulting to an image with “tap here” instructions), and an iframe that specifically houses a page in which we’ll instantiate a Bing maps web control.9

You’ll see that some elements have style classes assigned to them. Those that start with win come from the WinJS stylesheet.10 You can browse these in Blend by using the Style Rules tab, shown in Figure 2-9. Other styles like titlearea, pagetitle, and group-title are meant for you to define in your own stylesheet, thereby overriding the WinJS styles for particular elements.

Image

FIGURE 2-9 In Blend, the Style Rules tab lets you look into the WinJS stylesheet and see what each particular style contains. Take special notice of the search bar under the tabs. This is here so you don’t waste your time visually scanning for a particular style—just start typing in the box, and let the computer do the work!

The page we’ll load into the iframe, map.html, is part of our app package that we’ll add in a moment, but note how we reference it. The ms-appx-web:/// protocol indicates that the iframe and its contents will run in the web context (introduced in Chapter 1), thereby allowing us to load the remote script for the Bing maps control. The triple slash, for its part—or more accurately the third slash—is shorthand for “the current app package” (a value that you can obtain from document.location.host), so we don’t need to create an absolute URI for in-package content.

To indicate that a page should be loaded in the local context, the protocol is just ms-appx://. It’s important to remember that no script is shared between these contexts (including variables and functions), relative paths stay in the same context, and communication between the two goes through the HTML5 postMessage function, as we’ll see later. All of this prevents an arbitrary website from driving your app and accessing WinRT APIs.

I’ve also included various aria-* attributes on these elements (as the templates do) that support accessibility. We’ll look at accessibility in detail in Chapter 17, “Apps for Everyone,” but it’s an important enough consideration that we should be conscious of it from the start: a majority of Windows users use accessibility features in some way. And although some aspects of accessibility are easy to add later on, adding aria-* attributes in markup is best done early.

In Chapter 17 we’ll also see how to separate strings (including ARIA labels) from our markup, JavaScript, and even the manifest and place it in a resource file. This is something you might want to do from early on, so see the “Preparing for Localization” section in that chapter for the details. Note, however, that resource lookup doesn’t work well in Blend, so you might want to hold off on the effort until you’ve done most of your styling.

Styling in Blend

At this point, and assuming you were paying enough attention to read the footnotes, Blend’s real-time display of the app shows an obvious need for styling, just like raw markup should. See Figure 2-10.

Image

FIGURE 2-10 The app in Blend without styling, showing a view that is much like the Visual Studio simulator. If the taphere.png image doesn’t show after adding it, use the View/Refresh menu command.

The tabs along the upper left in Blend give you access to your Project files, Assets like all the controls you can add to your UI, and a browser for all the Style Rules defined in the environment. On the lower left side, the Live DOM area lets you browse your element hierarchy and the Device tabs lets you set orientation, screen resolution, and view state. Clicking an element in the Live DOM here will highlight it in the designer, just like clicking an element in the designer will highlight it in the Live DOM section.

Over on the right side you see what will become a very good friend: the section for HTML Attributes and CSS Properties. In the latter case, the list at the top shows all the sources for styles that are being applied to the currently selected element and where exactly those styles are coming from (often a headache with CSS). What’s selected in that box, mind you, will determine where changes in the properties pane below will be written, so be very conscious of your selection!

Now to get our gauche, unstylish page to look like the wireframe, we need to go through the elements and create the necessary selectors and styles. First, I recommend creating a 1x1 grid in the body element as this makes Blend’s display in the artboard work better at present. So add display: -ms-grid; -ms-grid-rows: 1fr; -ms-grid-columns: 1fr; to default.css for that element.

CSS grids also make this app’s layout fairly simple: we’ll just use a couple of nested grids to place the main sections and the subsections within them, following the general pattern of styling that works best in Blend:

• Set the insertion point of the style rule with the orange-yellow line control within Blend’s Style Rules tab. This determines exactly where any new rule you create will be created:

Image

• Right-click the element you want to style in the Live DOM, and select Create Style Rule From Element Id or Create Style Rule From Element Class.

Note If both of these items are disabled, go to the HTML Attributes pane (upper right) and add an id, class, or both. Otherwise you’ll be hand-editing the stylesheets later on to move styles around (especially inline style), so you might as well save yourself the trouble.

This will create a new style rule in the app’s stylesheet (e.g., default.css). In the CSS properties pane on the right, then, find the rule that was created and add the necessary style properties in the pane below.

• Repeat with every other element.

So for the mainContent div, we create a rule from the Id and set it up with display: -ms-grid; -ms-grid-columns: 1fr; and -ms-grid-rows: 128px 1fr 60px;. (See Figure 2-11.) This creates the basic vertical areas for the wireframes. In general, you won’t want to put left or right margins directly in this grid because the lower section will often have horizontally scrolling content that should bleed off the left and right edges. In our case we could use one grid, but instead we’ll add those margins in a nested grid within the header and section elements.

Image

FIGURE 2-11 Setting the grid properties for the mainContent div. Notice how the View Set Properties Only checkbox (upper right) makes it easy to see what styles are set for the current rule. Also notice in the main “Artboard” how the grid rows and columns are indicated, including sliders (circled) to manipulate rows and columns directly in the artboard.

Showing this and the rest of the styling—going down into each level of the markup and creating appropriate styles in the appropriate media queries for the view states—is best done in video. Video 2-2 (available with this book’s downloadable companion content) shows this process starting with the creation of the project, styling the different view states, and switching to Visual Studio (right-click the project name in Blend and select Edit In Visual Studio) to run the app in the simulator as a verification. It also demonstrates the amount of time it takes to style such an app once you’re familiar with the tools.

The result of all this in the simulator looks just like the wireframes—see Figures 2-12 through 2-14—and all the styling is entirely contained within the appropriate media queries of default.css. Most importantly, the way Blend shows us the results in real time is an enormous time-saver over fiddling with the CSS and running the app all over again, a painful process that I’m sure you’re familiar with! (And the time savings are even greater with Interactive Mode; see Video 4-1 in the companion content created for Chapter 4, “Controls, Control Styling, and Data Binding.”)

Image

FIGURE 2-12 Full-screen landscape view.

Image

FIGURE 2-13 Filled view (landscape only).

Image

FIGURE 2-14 Snapped view (landscape only) and full-screen portrait view; these are to relative scale.

Adding the Code

Let’s complete the implementation now in Visual Studio. Again, right-click the project name in Blend’s Project tab and select Edit In Visual Studio if you haven’t already. Note that if your project is already loaded into Visual Studio when you switch to it, it will (by default) prompt you to reload changed files. Say yes.11 At this point, we have the layout and styles for all the necessary view states, and our code doesn’t need to care about any of it except to make some minor refinements, as we’ll see in a moment.

What this means is that, for the most part, we can just write our app’s code against the markup and not against the markup plus styling, which is, of course, a best practice with HTML/CSS in general. Here are the features that we’ll now implement:

• A Bing maps control in the Location section showing the user’s current location. We’ll just show this map automatically, so there’s no control to start this process.

• Use the WinRT APIs for camera capture to get a photograph in response to a tap on the Photo img element.

• Provide the photograph and the location data to the Share charm when the user invokes it.

Figure 2-15 shows what the app will look like when we’re done.

Image

FIGURE 2-15 The completed Here My Am! app (though I zoomed out the map so you can’t quite tell exactly where I live!).

Creating a Map with the Current Location

For the map, we’re using a Bing maps web control instantiated through the map.html page that’s loaded into an iframe of the main page. This page loads the Bing Maps control script from a remote source and thus runs in the web context. Note that we could also employ the Bing Maps SDK, which provides script we can load into the local context. For the time being, I want to use the remote script approach because it gives us an opportunity to work with web content and the web context in general, something that I’m sure you’ll want to understand for your own apps. We’ll switch to the local control in Chapter 8, “State, Settings, Files, and Documents.”

That said, let’s put map.html in an html folder. Right-click the project and select Add/New Folder (entering html to name it). Then right-click that folder, select Add/New Item…, and then select HTML Page. Once the new page appears, replace its contents with the following:12

<!DOCTYPE html>
<html>
    <head>
        <title>Map</title>
        <script type="text/javascript"
            src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>

        <script type="text/javascript">
            //Global variables here
            var map = null;

            document.addEventListener("DOMContentLoaded", init);
            window.addEventListener("message", processMessage);

            //Function to turn a string in the syntax { functionName: ..., args: [...] }
            //into a call to the named function with those arguments. This constitutes a generic
            //dispatcher that allows code in an iframe to be called through postMessage.
            function processMessage(msg) {
                //Verify data and origin (in this case the local context page)
                if (!msg.data || msg.origin !== "ms-appx://" + document.location.host) {
                    return;
                }

                var call = JSON.parse(msg.data);

                if (!call.functionName) {
                    throw "Message does not contain a valid function name.";
                }

                var target = this[call.functionName];

                if (typeof target != 'function') {
                    throw "The function name does not resolve to an actual function";
                }

                return target.apply(this, call.args);
            }


            function notifyParent(event, args) {
                //Add event name to the arguments object and stringify as the message
                args["event"] = event;
                window.parent.postMessage(JSON.stringify(args),
                    "ms-appx://" + document.location.host);
            }

            //Create the map (though the namespace won't be defined without connectivity)
            function init() {
                if (typeof Microsoft == "undefined") {
                    return;
                }

                map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), {
                    //NOTE: replace these credentials with your own obtained at
                    //http://msdn.microsoft.com/en-us/library/ff428642.aspx
                    credentials: "...",
                    //zoom: 12,
                    mapTypeId: Microsoft.Maps.MapTypeId.road
                });
            }

            function pinLocation(lat, long) {
                if (map === null) {
                    throw "No map has been created";
                }

                var location = new Microsoft.Maps.Location(lat, long);
                var pushpin = new Microsoft.Maps.Pushpin(location, { draggable: true });

                Microsoft.Maps.Events.addHandler(pushpin, "dragend", function (e) {
                    var location = e.entity.getLocation();
                    notifyParent("locationChanged",
                        { latitude: location.latitude, longitude: location.longitude });
                });

                map.entities.push(pushpin);
                map.setView({ center: location, zoom: 12, });
                return;
            }

            function setZoom(zoom) {
                if (map === null) {
                    throw "No map has been created";
                }

                map.setView({ zoom: zoom });
            }
        </script>
    </head>
    <body>
        <div id="mapDiv"></div>
    </body>
</html>

Note that the JavaScript code here could be moved into a separate file and referenced with a relative path, no problem. I’ve chosen to leave it all together for simplicity.

At the top of the page you’ll see a remote script reference to the Bing Maps control. We can reference remote script here because the page is loaded in the web context within the iframe (ms-appx-web:// in default.html). You can then see that the init function is called on DOMContent-Loaded and creates the map control. Then we have a couple of other methods, pinLocation and setZoom, which can be called from the main app as needed.

Of course, because this page is loaded in an iframe in the web context, we cannot simply call those functions directly from our app code. We instead use the HTML5 postMessage function, which raises a message event within the iframe. This is an important point: the local and web contexts are kept separate so that arbitrary web content cannot drive an app or access WinRT APIs. The two contexts enforce a boundary between an app and the web that can only be crossed with postMessage.

In the code above, you can see that we pick up such messages and pass them to the process-Message function, a little generic routine that turns a JSON string into a local function call, complete with arguments.

To see how this works, let’s look at how we call pinLocation from within default.js. To make this call, we need some coordinates, which we can get from the WinRT Geolocation APIs. We’ll do this within the onactivated handler, so the user’s location is just set on startup (and saved in the lastPosition variable sharing later on):

//Drop this after the line: var activation = Windows.ApplicationModel.Activation;
var lastPosition = null;


//Place this after args.setPromise(WinJS.UI.processAll());
var gl = new Windows.Devices.Geolocation.Geolocator();

gl.getGeopositionAsync().done(function (position) {
    //Save for share
    lastPosition = { latitude: position.coordinate.latitude,
        longitude: position.coordinate.longitude };

    callFrameScript(document.frames["map"], "pinLocation",
        [position.coordinate.latitude, position.coordinate.longitude]);
    });

where callFrameScript is just a little helper function to turn the target element, function name, and arguments into an appropriate postMessage call:

//Place this before app.start();
function callFrameScript(frame, targetFunction, args) {
    var message = { functionName: targetFunction, args: args };
    frame.postMessage(JSON.stringify(message), "ms-appx-web://" + document.location.host);
}

A few points about this code. To obtain coordinates, you can use the WinRT geolocation API or the HTML5 geolocation API. The two are almost equivalent, with slight differences described in Chapter 9, “Input and Sensors,” in “Sidebar: HTML5 Geolocation.” The API exists in WinRT because other supported languages (C# and C++) don’t have access to the HTML5 geolocation APIs. We’re focused on WinRT APIs in this book, so we’ll just use functions in the Windows.Devices.Geolocation namespace.

Next, in the second parameter to postMessage you see a combination of ms-appx[-web]:// with document.location.host. This essentially means “the current app from the local [or web] context,” which is the appropriate origin of the message. Notice that we use the same value to check the origin when receiving a message: the code in map.html verifies it’s coming from the app’s local context, whereas the code in default.js verifies that it’s coming from the app’s web context. Always make sure to check the origin appropriately; see Validate the origin of postMessage data in Developing secure apps.

Finally, the call to getGeopositionAsync has an interesting construct, wherein we make the call and chain this function called done onto it, whose argument is another function. This is a very common pattern we’ll see while working with WinRT APIs, as any API that might take longer than 50ms to complete runs asynchronously. This conscious decision was made so that the API surface area led to fast and fluid apps by default.

In JavaScript, such APIs return what’s called a promise object, which represents results to be delivered at some time in the future. Every promise object has a done method whose first argument is the function to be called upon completion, the completed handler. It can also take two optional functions to wire up error and progress handlers as well. We’ll see more about promises as we progress through this book, such as the then function that’s just like done but allows further chaining (Chapter 3), and how promises fit into async operations more generally (Chapter 16, “WinRT Components”).

The argument passed to the completed handler contains the results of the async call, which in our example above is a Windows.Geolocation.Geoposition object containing the last reading. (When reading the docs for an async function, you’ll see that the return type is listed like IAsyncOperation-<Geoposition>. The name within the <> indicates the actual data type of the results, so you’ll follow the link to that topic for the details.) The coordinates from this reading are what we then pass to the pinLocation function within the iframe, which in turn creates a pushpin on the map at those coordinates and then centers the map view at that same location.13

One final note about async APIs. Within the WinRT API, all async functions have “Async” in their names. Because this isn’t common practice within JavaScript toolkits or the DOM API, async functions within WinJS don’t use that suffix. In other words, WinRT is designed to be language-neutral, but WinJS is designed to follow typical JavaScript conventions.

Oh Wait, the Manifest!

Now you may have tried the code above and found that you get an “Access is denied” exception when you try to call getGeopositionAsync. Why is this? Well, the exception says we neglected to set the Location capability in the manifest. Without that capability set, calls like this that depend on that capability will throw an exception.

If you were running in the debugger, that exception is kindly shown in a dialog box. If you run the app outside of the debugger—from the tile on your Start screen—you’ll see that the app just terminates without showing anything but the splash screen. This is the default behavior for an unhandled exception. To prevent that behavior, add an error-handling function as the second parameter to the async promise’s done method:

gl.getGeopositionAsync().done(function (position) {
    //...
}, function(error) {
    console.log("Unable to get location.");
});

The console.log function writes a string to the JavaScript Console window in Visual Studio, which is obviously a good idea. Now run the app outside the debugger and you’ll see that it comes up, because the exception is now considered “handled.” In the debugger, set a breakpoint on the console.log line inside and you’ll hit that breakpoint after the exception appears and you press Continue. (This is all we’ll do with the error for now; in Chapter 7, “Commanding UI,” we’ll add a better message and a retry command.)

If the exception dialog gets annoying, you can control which exceptions pop up like this in the Debug > Exceptions dialog box (shown in Figure 2-16), under JavaScript Runtime Exceptions. If you uncheck the box under User-unhandled, you won’t get a dialog when that particular exception occurs.

Image

FIGURE 2-16 JavaScript run-time exceptions in the Debug/Exceptions dialog of Visual Studio.

Back to the capability: to get the proper behavior for this app, open package.appxmanifest in your project, select the Capabilities tab, and check Location, as shown in Figure 2-17.

Image

FIGURE 2-17 Setting the Location capability in Visual Studio’s manifest editor. (Note that Blend supports editing the manifest only as XML.)

Now, even when we declare the capability, geolocation is still subject to user consent, as mentioned in Chapter 1. When you first run the app with the capability set, then, you should see a popup like Figure 2-18. If the user blocks access here, the error handler will again be invoked as the API will throw an Access denied exception.

Image

FIGURE 2-18 A typical consent popup, reflecting the user’s color scheme, that appears when an app first tries to call a brokered API (geolocation in this case). If the user blocks access, the API will fail, but the user can later change consent in the Settings/Permissions panel.

While debugging, you might notice that this popup appears only once, even across subsequent debugging sessions. To clear this state, invoke the Settings charm in the running app and select Permissions, and you’ll see toggle switches for all the relevant capabilities. If for some reason you can’t run the app at all, go to the Start screen and uninstall the app from its tile. You’ll then see the popup when you next run the app.

Note that there isn’t a notification when the user changes these Permission settings. The app can detect a change only by attempting to use the API again. We’ll revisit this in Chapter 8.

Capturing a Photo from the Camera

In a slightly twisted way, I hope the idea of adding camera capture within a so-called “quickstart” chapter has raised serious doubts in your mind about this author’s sanity. Isn’t that going to take a whole lot of code? Well, it used to, but it doesn’t on Windows 8. All the complexities of camera capture have been nicely encapsulated within the Windows.Media.Capture API to such an extent that we can add this feature with only a few lines of code. It’s a good example of how a little dynamic code like JavaScript combined with well-designed WinRT components—both those in the system and those you can write yourself—make a very powerful combination!

To implement this feature, we first need to remember that the camera, like geolocation, is a privacy-sensitive device and must also be declared in the manifest, as shown in Figure 2-19.

Image

FIGURE 2-19 The camera capability in Visual Studio’s manifest editor.

On first use of the camera at run time, you’ll see another consent dialog like the one shown in Figure 2-20.

Image

FIGURE 2-20 Popup for obtaining the user’s consent to use the camera. You can control these through the Settings/Permissions panel at any time.

Next we need to wire up the img element to pick up a tap gesture. For this we simply need to add an event listener for click, which works for all forms of input (touch, mouse, and stylus), as we’ll see in Chapter 9:

var image = document.getElementById("photo");
image.addEventListener("click", capturePhoto.bind(image));

Here we’re providing capturePhoto as the event handler, and using the function object’s bind method to make sure the this object inside capturePhoto is bound directly to the img element. The result is that the event handler can be used for any number of elements because it doesn’t make any references to the DOM itself:

//Place this under var lastPosition = null;
var lastCapture = null;


//Place this after callFrameScript
function capturePhoto() {
    //Due to the .bind() call in addEventListener, "this" will be the image element,
    //but we need a copy for the async completed handler below.
    var that = this;

    var captureUI = new Windows.Media.Capture.CameraCaptureUI();

    //Indicate that we want to capture a PNG that's no bigger than our target element --
    //the UI will automatically show a crop box of this size
    captureUI.photoSettings.format = Windows.Media.Capture.CameraCaptureUIPhotoFormat.png;
    captureUI.photoSettings.croppedSizeInPixels =
        { width: this.clientWidth, height: this.clientHeight };

    captureUI.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.photo)
        .done(function (capturedFile) {
            //Be sure to check validity of the item returned; could be null if the user canceled.
            if (capturedFile) {
                lastCapture = capturedFile; //Save for Share
                that.src = URL.createObjectURL(capturedFile, {oneTimeOnly: true});
            }
        }, function (error) {
            console.log("Unable to invoke capture UI.");
        });
}

We do need to make a local copy of this within the click handler, though, because once we get inside the async completed function (see the function inside captureFileAsync.done) we’re in a new function scope and the this object will have changed. The convention for such a copy of this is to call it that. Got that?

To invoke the camera UI, we only need create an instance of Windows.Media.Capture.-CameraCaptureUI with new (a typical step to instantiate dynamic WinRT objects), configure it with the desired format and size (among many other possibilities as discussed in Chapter 10, “Media”), and then call captureFileAsync. This will check the manifest capability and prompt the user for consent, if necessary.

This is an async call, so we hook a .done on the end with a completed handler, which in this case will receive a Windows.Storage.StorageFile object. Through this object you can get to all the raw image data you want, but for our purpose we simply want to display it in the img element. That’s easy as well! You can hand a StorageFile object to the URL.createObjectURL method and get back an URI that can be directly assigned to the img.src attribute. The captured photo appears!14

Note that captureFileAsync will call the completed handler if the UI was successfully invoked but the user hit the back button and didn’t actually capture anything. This is why the extra check is there for the validity of capturedFile. An error handler on the promise will, for its part, pick up failures to invoke the UI in the first place, but note that a denial of consent will show a message in the capture UI directly (see Figure 2-21), so it’s unnecessary to have an error handler for that purpose with this particular API. In most cases, however, you’ll want to have an error handler in place for async calls.

Image

FIGURE 2-21 The camera capture UI’s message when consent is denied (left); you can change permissions through the Settings Charm > Permissions pane (right).

Sharing the Fun!

Taking a goofy picture of oneself is fun, of course, but sharing the joy with the rest of the world is even better. Up to this point, however, sharing information through different social media apps has meant using the specific APIs of each service. Workable, but not scalable.

Windows 8 has instead introduced the notion of the share contract, which is used to implement the Share charm with as many apps as participate in the contract. Whenever you’re in an app and invoke Share, Windows asks the app for its source data. It then examines that data, generates a list of target apps that understand the data formats involved (according to their manifests), and displays that list in the Share pane. When the user selects a target, that app is activated and given the source data. In short, the contract is an abstraction that sits between the two, so the source and target apps never need to know anything about each other.

This makes the whole experience all the richer when the user installs more share-capable apps, and it doesn’t limit sharing to only well-known social media scenarios. What’s also beautiful in the overall experience is that the user never leaves the original app to do sharing—the share target app shows up in its own view as an overlay that only partially obscures the source app. This way, the user immediately returns to that source app when the sharing is completed, rather than having to switch back to that app manually. In addition, the source data is shared directly with the target app, so the user never needs to save data to intermediate files for this purpose.

So instead of adding code to our app to share the photo and location to a particular target, like Facebook, we only need to package the data appropriately when Windows asks for it.

That asking comes through the datarequested event sent to the Windows.ApplicationModel.-DataTransfer.DataTransferManager object.15 First we just need to set up an appropriate listener—place this code is in the activated event in default.js after setting up the click listener on the img element:

var dataTransferManager =
    Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();
dataTransferManager.addEventListener("datarequested", provideData);

The idea of a current view is something that we’ll see pop up now and then. It reflects that an app can be launched for different reasons—such as servicing a contract—and thus presents different underlying pages or views to the user at those times. These views (unrelated to the snap/fill/etc. view states) can be active simultaneously. To thus make sure that your code is sensitive to these scenarios, certain APIs return objects appropriate for the current view of the app as we see here.

For this event, the handler receives a Windows.ApplicationModel.DataTransfer.DataRequest object in the event args (e.request), which in turn holds a DataPackage object (e.request.data). To make data available for sharing, you populate this data package with the various formats you have available. (We’ve saved these in lastPosition and lastCapture.) In our case, we make sure we have position and a photo and then fill in text and image properties (if you want to obtain a map from Bing for sharing purposes, see Get a static map):

//Drop this in after capturePhoto
function provideData(e) {
    var request = e.request;
    var data = request.data;

    if (!lastPosition || !lastCapture) {
        //Nothing to share, so exit
        return;
    }

    data.properties.title = "Here My Am!";

    data.properties.description = "At ("
        + lastPosition.latitude + ", " + lastPosition.longitude + ")";

    //When sharing an image, include a thumbnail
    var streamReference =
        Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(lastCapture);
    data.properties.thumbnail = streamReference;

    //It's recommended to always use both setBitmap and setStorageItems for sharing a single image
    //since the target app may only support one or the other.

    //Put the image file in an array and pass it to setStorageItems
    data.setStorageItems([lastCapture]);

    //The setBitmap method requires a RandomAccessStream.
    data.setBitmap(streamReference);
}

The latter part of this code is pretty standard stuff for sharing a file-based image (which we have in lastCapture). I got most of this code, in fact, directly from the Share content source app sample, which we’ll look at more closely in Chapter 12, “Contracts.”

With this last addition of code, and a suitable sharing target installed (such as the Share content target app sample, as shown in Figure 2-22), we now have a very functional app—in all of 35 lines of HTML, 125 lines of CSS, and less than 100 lines of JavaScript!

Image

FIGURE 2-22 Sharing (monkey-see, monkey-do!) to the Share target sample in the Windows SDK. Share targets appear as a partial overlay on top of the current app, so the user never leaves the app context.

Extra Credit: Receiving Messages from the iframe

There’s one more piece I’ve put into Here My Am! to complete the basic interaction between app and iframe content: the ability to post messages from the iframe back to the main app. In our case, we want to know when the location of the pushpin has changed so that we can update lastPosition.

First, here’s a simple utility function I added to map.html to encapsulate the appropriate postMessage calls to the app from the iframe:

function function notifyParent(event, args) {
    //Add event name to the arguments object and stringify as the message
    args["event"] = event;
    window.parent.postMessage(JSON.stringify(args), "ms-appx://" + document.location.host);
}

This function basically takes an event name, adds it to whatever an object containing parameters, stringifies the whole thing, and then posts it back to the parent.

When a pushpin is dragged, Bing maps raises a dragend event, which we’ll wire up and handle in the setLocation function just after the pushpin is created (also in map.html):

var pushpin = new Microsoft.Maps.Pushpin(location, { draggable: true });

Microsoft.Maps.Events.addHandler(pushpin, "dragend", function (e) {
    var location = e.entity.getLocation();
    notifyParent("locationChanged",
        { latitude: location.latitude, longitude: location.longitude });
});

Back in default.js (the app), we add a listener for incoming messages inside app.onactivated:

window.addEventListener("message", processFrameEvent);

where the processFrameEvent handler looks at the event in the message and acts accordingly:

function processFrameEvent (message) {
    //Verify data and origin (in this case the web context page)
    if (!message.data || message.origin !== "ms-appx-web://" + document.location.host) {
        return;
    }

    if (!message.data) {
        return;
    }

    var eventObj = JSON.parse(message.data);

    switch (eventObj.event) {
        case "locationChanged":
            lastPosition = { latitude: eventObj.latitude, longitude: eventObj.longitude };
            break;

        default:

            break;
    }
};

Clearly, this is more code than we’d need to handle a single message or event from an iframe, but I wanted to give you something that could be applied more generically in your own apps.

The Other Templates

In this chapter we’ve worked only with the Blank App template so that we could understand the basics of writing a Windows Store app without any other distractions. In Chapter 3, we’ll look more deeply at the anatomy of apps through a few of the other templates, yet we won’t cover them all. We’ll close this chapter, then, with a short introduction to these very handy tools.

Fixed Layout Template

“A project for a Windows Store app that scales using a fixed aspect ratio layout.” (Blend/Visual Studio description)

What we’ve seen so far are examples of apps that adapt themselves to changes in display area by adjusting the layout. In Here My Am!, we used CSS grids with self-adjusting areas (those 1fr’s in rows and columns). This works great for apps with content that is suitably resizable as well as apps that can show additional content when there’s more room, such as more news headlines or items from a search.

As we’ll see in Chapter 6, other kinds of apps are not so flexible, such as games where the aspect ratio of the playing area needs to stay constant. (It would not be fair if players on larger screens got to see more of the game!) So, when the display area changes—either from view states or a change in display resolution—they do better to scale themselves up or down rather than adjust their layout.

The Fixed Layout template provides the basic structure for such an app, just like the Blank template provides for a flexible app. The key piece is the WinJS.UI.ViewBox control, which automatically takes care of scaling its contents while maintaining the aspect ratio:

<body>
    <div data-win-control="WinJS.UI.ViewBox">
        <div class="fixedlayout">
            <p>Content goes here</p>
        </div>
    </div>
</body>

In default.css, you can see that the body element is styled as a CSS flexbox centered on the screen and the fixedLayout element is set to 1024x768 (the minimum size for the fullscreen-landscape and filled view states). Within the child div of the ViewBox, then, you can safely assume that you’ll always be working with these fixed dimensions. The ViewBox will scale everything up and provide letterboxing or sidepillars as necessary.

Note that such apps might not be able to support an interactive snapped state; a game, for example, will not be playable when scaled down. In this case an app can simply pause the game and try to unsnap itself when the user taps it again. We’ll revisit this in Chapter 6.

Navigation Template

“A project for a Windows Store app that has predefined controls for navigation.” (Blend/Visual Studio description)

The Navigation template builds on the Blank template by adding support for page navigation. As discussed in Chapter 1, Windows Store apps written in JavaScript are best implemented by having a single HTML page container into which other pages are dynamically loaded. This allows for smooth transitions (as well as animations) between those pages and preserves the script context.

This template, and the others that remain, employ a Page Navigator control that facilitates loading (and unloading) pages in this way. You need only create a relatively simple structure to describe each page and its behavior. We’ll see this in Chapter 3.

In this model, default.html is little more than a simple container, with everything else in the app coming through subsidiary pages. The Navigation template creates only one subsidiary page, yet it establishes the framework for how to work with multiple pages.

Grid Template

“A three-page project for a Windows Store app that navigates among grouped items arranged in a grid. Dedicated pages display group and item details.” (Blend/Visual Studio description)

Building on the Navigation template, the Grid template provides the basis for apps that will navigate collections of data across multiple pages. The home page shows grouped items within the collection, from which you can then navigate into the details of an item or into the details of a group and its items (from which you can then go into item details as well).

In addition to the navigation, the Grid template also shows how to manage collections of data through the WinJS.Binding.List class, a topic we’ll explore much further in Chapter 5, “Collections and Collection Controls.” It also provides the structure for an app bar and shows how to simplify the app’s behavior in snap view.

The name of the template, by the way, derives from the particular grid layout used to display the collection, not from the CSS grid.

Split Template

“A two-page project for a Windows Store app that navigates among grouped items. The first page allows group selection while the second displays an item list alongside details for the selected item.” (Blend/Visual Studio description)

This last template also builds on the Navigation template and works over a collection of data. Its home page displays a list of groups, rather than grouped items as with the Grid template. Tapping a group then navigates to a group detail page split into two (hence the template name). The left side contains a vertically panning list of items; the right side shows details for the currently selected item.

Like the Grid template, the Split template provides an app bar structure and handles both snap and portrait views intelligently. That is, because vertically oriented views don’t lend well to splitting the display (contrary to the description above!), the template shows how to switch to a page navigation model within those view states to accomplish the same ends.

What We’ve Just Learned

• How to create a new Windows Store app from the Blank app template.

• How to run an app inside the local debugger and within the simulator, as well as the role of remote machine debugging.

• The features of the simulator that include the ability to simulate touch, set view states, and change resolutions and pixel densities.

• The basic project structure for Windows Store apps, including WinJS references.

• The core activation structure for an app through the WinJS.Application.onactivated event.

• The role and utility of design wireframes in app development, including the importance of designing for all view states, where the work is really a matter of element visibility and layout.

• The power of Blend for Visual Studio to quickly and efficiently add styling to an app’s markup. Blend also makes a great CSS debugging tool.

• How to safely use web content (such as Bing maps) within a web context iframe and communicate between that page and the local context app by using the postMessage method.

• How to use the WinRT APIs, especially async methods involving promises but also geolocation and camera capture. Async operations return a promise to which you provide a completed handler (and optional error and progress handlers) to the promise’s then or done method.

• Manifest capabilities determine whether an app can use certain WinRT APIs. Exceptions will result if an app attempts to use an API without declaring the associated capability.

• How to share data through the Share contract by responding to the datarequested event.

• Kinds of apps supported through the other app templates: Fixed Layout, Navigation, Grid, and Split.