WinJS.log is an interesting function. Though it's ostensibly part of the WinJS namespace, it's not actually directly implemented within WinJS itself! At the same time, it's used all over the place within the library. Take a look throughout the base.js and ui.js files of WinJS and you'll see many lines like this:

WinJS.log && WinJS.log(safeSerialize(e), "winjs", "error");

That is, WinJS checks if WinJS.log exists, and if so, outputs some log informaion for many different kinds of conditions, primarily error conditions. In other words, this logging will tell you various things that are happening inside WinJS.

To see all that output, though, you need to provide an implementation of WinJS.log yourself; that is, you need to assign some function to this particular variable. That function, as described in the documentation, should accept three parameters:

  1. The message to log
  2. A string with a tag or tags to categorize the message. WinJS always uses "winjs" and sometimes adds an additional tag like "binding" in which case the second parameter is "winjs binding"
  3. A string describing the type of the message. WinJS will use "error", "info", "warn", and "perf"

The simplest way to do this is just map WinJS.log to console.log like so:

WinJS.log = console.log.bind(console);

But this doesn't make for very nice output. For example, this call:

WinJS.log("message", "tag", "type");

Will create the output "messagetagtype" all smooshed together.

To make things a little better, WinJS itself offers a basic implementation of a logger, which is set up by calling WinJS.Utilities.startLog:

WinJS.Utilities.startLog();

Calling this with no parameters, as shown here, sets WinJS.log to a basic function that formats the output a little more nicely using WinJS.Utilities.formatLog (which you can call directly), and outputs the result to the console. So the same test call above will then appear on the console as "type: tag: message".

If you want to filter for specific tags, which is especially useful if you're using WinJS.log in your own code and use tags to identify the module you're calling from, then you can reduce the output. The syntax is to just pass a string with tags separated by spaces. So this code:

WinJS.Utilities.startLog("tag1 tag2");
WinJS.log("message", "tag1", "type");
WinJS.log("message", "tag2", "type");
WinJS.log("message", "tag3", "type");
WinJS.log("message", "tag4", "type");

Will output two lines, "type: tag1: message" and "type: tag2: message" but ignore the other two.

You can actually do much more with that one parameter by passing an object that specified additional options, such as filtering the type and so forth. See the WinJS.Utilities.startLog documentation for details.

Note also that if you call WinJS.Utilities.startLog multiple times, it aggregates the tags you're using. This means you can call it from different modules where each module starts logging for itself.

When you're done logging, you can call WinJS.Utilities.stopLog, which just calls delete WinJS.log. This is an all-or-nothing call, though–you can't remove individual tags from the logging.

All that said, you can certainly do more interesting things with WinJS.log if you want. You could, for example, have the function call msWriteProfilerMark and use it more for perf checking than error logging (in which case you can filter on a type of "perf" or something like that).

With console.log, it's helpful to know that you can, if desired, save that output in the system Event Log, visible in Event Viewer. The steps to do that are as follows:

  1. Launch Event viewer (eventvwr.exe)
  2. Under Application And ServicesMicrosoftWindowsAppHost node, use the context menu to View->Show Analytic and Debug Logs
  3. Once the App Tracing channel shows up under the AppHost node, use the context menu to “Enable Log”
  4. Restart your app
  5. The console messages should now be in event viewer

You'll see a bunch of other events from wwahost.exe showing up here too, but you can filter on your process ID to whittle down the list. It's best to be running only your app when checking the Event Viewer!

Finally, if you use WinJS.log, you'll want to make sure it isn't being employed in release versions of your app. For this reason, when callign WinJS.log, use the same syntax as WinJS: WinJS.log && WinJS.log(…). This way you won't be spending extra cycles in your release version writing to a console that the user will never see.

Then be sure to remove the one line that assigns a function to WinJS.log (or calls WinJS.Utilities.startLog) before you build your package to upload to the Store. This is much easier than trying to scrub your app for direct console.log calls.

Thanks to Josh Williams and Andy Sterland who provided many of the details here.


In Part 1 we looked at basic class definitions using WinJS.Class and how this helper gives you a structure through which you can define classes without directly messing with object prototypes.

In this part we’ll look at the next piece in WinJS.Class, namely WinJS.Class.derive. As you’d expect, this method allows you to basically add instance and static members to an existing class. The syntax is:

WinJS.Class.derive(baseClass, constructor, instanceMembers, staticMembers);

where baseClass is the name of a class previously defined with WinJS.Class.define or WinJS.Class.derive, or, for that matter, really any other object. The other three parameters are the same as those of WinJS.Class.define, with the same meaning.

Peeking into the WinJS sources (base.js), we can see how derive works:

if (baseClass) {
    constructor = constructor || function () { };
    var basePrototype = baseClass.prototype;
constructor.prototype = Object.create(basePrototype);
WinJS.Utilities.markSupportedForProcessing(constructor);

    Object.defineProperty(constructor.prototype, “constructor”, { value: constructor, writable: true, configurable: true, enumerable: true });

    if (instanceMembers) {
        initializeProperties(constructor.prototype, instanceMembers);
}

    if (staticMembers) {
        initializeProperties(constructor, staticMembers);
}

    return constructor;
} else {
    return define(constructor, instanceMembers, staticMembers);
}

You can see that if baseClass is null, derive is just an alias for define, and if you indicate null for the constructor, an empty function is provided. Otherwise you can see that the derived class is given a copy of the base class’ prototype, so that the two won’t interfere with each other. After that, derive then adds the static and instance properties as did define.

Because baseClass already has its own instance and static members, they’re already present in its prototype, so those members carry over into the derived class, as you’d expect. But again, if you make later changes to members of that original baseClass, those changes only affect the derivation and not the original.

Looking around the rest of WinJS, you’ll see that derive is used in a variety of places to centralize implementation that’s shared between similar controls and data sources, for example.


Processing XML data is a common activity for web applications and will likely be employed by many Windows Store apps. For apps written in HTML, CSS, and JavaScript, two APIs are available: the XML DOM API represented by the DOMParser object, and the WinRT API in the Windows.Data.Xml.Dom namespace. This post will make a brief comparison between the two.

Note: one key difference for any comparison with WinRT APIs is that HTML and native JavaScript APIs are available in the web context whereas WinRT is not. This comparison therefore only applies to pages running in the local context. In the web context you must use the HTML5/JS APIs.

It’s also helpful to note that overlaps such as these exist (a) because of the local and web contexts, and (b) to provide the capability to Windows Store apps written in other languages where an intrinsic API is not available.

 

XML DOM API

The XML DOM API is already familiar to JavaScript developers, because the HTML DOM API is really just a specific flavor of the XML API. Functions like getElementById, for example, which every JavaScript developer can probably type in their sleep, is shared between both. The XML DOM API is compliant with the HTML5 Web DOM Core spec.

This API is the most extensive where manipulating XML is concerned. Converting XML text to an XML document is done with a simple call to DOMParser.parse; the API is then available on that document object.

As far as drawbacks are concerned, this API is synchronous and entirely based on having the XML as a string. No provision is made for loading the XML from another source. It also does not support XSLT or XPath.

For details on the implementation of DOMParser for Windows Store apps, the documentation is here.

 

WinRT API: Windows.Data.Xml.Dom

Generally speaking, the API available for an XML document in WinRT, Windows.Data.Xml.Dom, is very similar to the XML DOM API. It is compliant with the W3C DOM Core specification.

In its design, many method names match the DOM versions, such as getElementById. That said, the WinRT API isn’t quite as extensive as the DOM API. Compare, for example, the XML DOM’s API on an element to IXmlElement. Similarly, IXmlText in WinRT has a single method, SplitText, while the XML DOM Text object has quite a few more.

The WinRT API provides other functionality, however. It provides XSLT and XPath support, and can, in addition to synchronous parsing of in-memory XML, asynchronously load XML from a file or remote URL. An XML document object obtained from WinRT can also be used with other WinRT APIs.

 

Recommendations

In the end, the specific differences between these APIs will determine what’s best for you:

  1. By default, use XML DOM API (DOMParser) in an app. It is the web-friendliest API, works in the web compartment, and covers the majority of web scenarios.
  2. Use XML WinRT API where XML DOM API is insufficient. It is necessary if you need to use XSLT or XPath, need to pass XML objects to WinRT APIs, require async loading of XML from a file or remote URL, or if compliance with the W3C DOM Core spec is required.

 


Though my primary focus is on Windows Store apps written in HTML, CSS, and JavaScript, I do see plenty of C#/XAML material cross my inbox. In this case, there’s a helpful template available in the Visual Studio Code Gallery that closes the gap between the HTML/CSS and XAML presentation layers, namely doing variable-sized items in a collection control, otherwise known as cell-spanning. This is built into the WinJS ListView control but takes a little more work in a XAML GridView.

The template found on http://visualstudiogallery.msdn.microsoft.com/da65cc08-c4bf-4824-b483-9c8f53fb063c?SRC=Home helps close that gap. To quote the description: “VariableGridView is a subclass of GridView that supports variable sized children. When using the template, there should be no need to modify this class.”

 


To handle otherwise unhandled exceptions at the application level, you can use the window.onerror event or the WinJS.Application.onerror event.

The key difference between the two is that WinJS.Application.onerror handles only exceptions that occur within WinJS’s own event dispatching mechanism. This includes any exceptions that happen within asynchronous operations, as those involve promises and promises employ that dispatching mechanism. So that handler will see exceptions that come out of WinRT and other parts of WinJS. It won’t see errors that arise from elsewhere, however, such as if you’re using XmlHttpRequest directly instead of WinJS.xhr, or you throw an exception somewhere else in your code. Those you can only capture in window.onerror.

If you have both handlers in place, WinJS.Application.onerror will see any unhandled WinJS/WinRT exceptions first. If you don’t handle them there, they’ll go onto window.onerror.

Either way, it’s a good idea to have such handler in place in your debug build, as you can then catch any unhandled exception before you get to the ominous chunk of code in WinJS (terminateAppHandler) that calles MSApp.terminateApp().

 


Thanks for Chris Anderson of the WinJS team for this writeup.

As it’s easy to misuse the JavaScript for(in) syntax, it’s helpful to take a close look at array enumeration. For starters, let’s ask what’s better: forEach, or for?

Using forEach is generally acceptable for non-performance critical loops. This syntax is semantically obvious, performs well in most scenarios, and avoids many of the classic pitfalls of JavaScript development making it easy to read and author:

Assuming we have this array (used in all the examples here):

var myArray = [“a”, “b”, “c”, “d”];

we can iterate for forEach as follows:

myArray.forEach(function (element) {
console.log(element);
});
// prints a b c d

For performance-critical scenarios (“hot paths,” tight loops, etc.), a classic for loop is better because the Javascript interpreter can better optimize it. This is also necessary if you need to break from the loop, which you cannot do with forEach.

for (var i = 0, l = myArray.length; i < l; i++) {
console.log(myArray[i]);
};
// prints a b c d

It’s important to cache the array length outside of the loop comparison function (using variable l as above), as JavaScript will not do this for you. Be aware of your closures too, especially nested closures. For example:

for (var i = 0, l = myArray.length; i < l; i++) {
msQueueCallback(function () {
console.log(myArray[i]);
});
};
// prints “undefined” 4 times

If it wasn’t obvious why you get undefined in the output, don’t use this syntax. Instead, use a simple closure:

for (var i = 0, l = myArray.length; i < l; i++) {
(function (i) {
msQueueCallback(function () { console.log(myArray[i]); });
})(i);
};
// prints a b c d

Alternatively, you can do so with forEach:

myArray.forEach(function (element, index) {
console.log(index + “:” + element);
});
// prints 0:a 1:b 2:c 3:d

So what about for(in)?

JavaScript’s for(in) loop allows for enumeration of the keys of an item, thus:

for (var i in myArray) {
console.log(i);
};
// prints 0 1 2 3

Which is generally unexpected. The primary use case for for(in) is to enumerate the properties of an object:

var o = { x: 10, y: 20 };
for (var i in o) {
console.log(i);
};
// prints x y

In general, we recommend you use Object.keys to get the set of keys for an object, and then use the normal array enumeration:

var o = { x: 10, y: 20 };
Object.keys(o).forEach(function (element) {
console.log(element);
});
// prints x y

What about reverse enumeration (or your favorite optimization)?

It is true that in many cases enumerating through a collection in reverse is faster:

for (var i = myArray.length; i–;) {
console.log(myArray[i]);
};
// prints d c b a

However, maintaining this kind of code probably costs more in the long run to negate any gains you make in micro-performance. Unless you have real benchmark data to justify the complexity, it’s unlikely that playing tricks like this will actually improve most code in an app.


Much has been written in the community about object-oriented JavaScript, and various patterns have emerged to accomplish with JavaScript’s flexible nature the kinds of behaviors that are built directly into a language like C++. Having myself done plenty of C++ in the past, much more than true functional programming, I’ve found the object-oriented approach to be more familiar and comfortable.

One place OO programmers can hit a bump in JavaScript is the lack of a clear idea of a “class,” that is, the definition of a type of object that can be instantiated. JavaScript, in short, has not class keyword. Instead it has functions, and only functions. Conveniently, however, if you create a function that populates members of the this variable, the name of that function works exactly like the name of a class.

To borrow a snippet of code from Eloquent JavaScript (a book I like for its depth and brevity, and which is also available for free in electronic form, thank you Marijn), take following function named Rabbit:

function Rabbit(adjective) {
this.adjective = adjective;
this.speak = function (line) {
print(“The “, this.adjective, ” rabbit says ‘”, line, “‘”);
};
}

By itself, this function really doesn’t do anything meaningful. You can call it from wherever and this will end up being your global context. Maybe handy if you like to pollute the global namespace!

When used with the new operator, on the other hand, this type of function becomes an object constructor, and effectively defines a class as we know in OO programming. We can use it as follows:

var fuzzyBunny = new Rabbit(“cutie”);
fuzzyBunny.speak(“nibble, nibble!”);

As Marijn points out, using new with a constructor function like this has a nice side effect which is to assign the object’s constructor property with the constructor function itself. This is not true if you just create a function that returns a newly instantiated object.

To make our class even more object-oriented, the other thing that we typically do is assign default values to properties and assign methods within the class, rather than on individual instances. In the first example above, each instance gets a new copy of the anonymous function assigned to speak. It would be better to define that function such that a single copy is used by the different instances of the class. This is accomplished by assigning the function to the class’ prototype as so:

function Rabbit(adjective) {
this.adjective = adjective;
}

Rabbit.prototype.speak = function (line) {
print(“The “, this.adjective, ” rabbit says ‘”, line, “‘”);
};

Of course, having to write this syntax out for each and every member of the class that’s shared between instances is both cumbersome and prone to errors. Personally, I also like to avoid messing with prototype as you can really hurt yourself if you’re not careful.

Thus WinJS provides a helper that provides a cleaner syntax as well as clear separation between the constructor function, instance members, and static members: WinJS.Class.define:

var ClassName = WinJS.Class.define(constructor, instanceMembers, staticMembers);

where constructor is a function and instanceMembers and staticMembers are both objects. The general structure you see in code looks like this (you can find many examples in the WinJS source code itself):

var ClassName = WinJS.Class.define(
function ClassName_ctor() { //adding _ctor is conventional
},
{
//Instance members
},
{
//Static members
}
);

As many classes don’t have static members, the third parameter is often omitted. Also, if you pass null as the constructor, WinJS will substitute an empty function in its place. You can see this in the WinJS source code for define (base.js, comments added):

function define(constructor, instanceMembers, staticMembers) {
constructor = constructor || function () { };

    //Adds a supportedForProcessing property set to true. This is needed by
//WinJS.UI.process[All], WinJS.Binding.process, and WinJS.Resources.process.
WinJS.Utilities.markSupportedForProcessing(constructor);

    if (instanceMembers) {
initializeProperties(constructor.prototype, instanceMembers);
}

    if (staticMembers) {
initializeProperties(constructor, staticMembers);
}

    return constructor;
}

You can also see how define treats static and instance members (initializeProperties is a helper that basically iterates the object in the second parameter and copies its members to the object in the first). Static members are specifically added as properties to the class function itself, constructor. This means they exist singularly on that object—if you change them anywhere, those changes apply to all instance. I consider that a rather dangerous practice, so I like to consider static members as read-only.

Instance members, on the other hand, are specifically added to constructor.prototype, so they are defined just once (especially in the case of methods) while still giving each individual instance a copy of the properties that can be changed without affecting other instances.

You can see, then, that WinJS.Class.define is really just a helper: you can accomplish everything it does with straight JavaScript, but you end up with code that’s generally harder to maintain. Indeed, the team that wrote WinJS really needed these structures for themselves to avoid making lots of small mistakes. But otherwise there is nothing magical about WinJS.Class.define, and you can use it in your own app code or not.

Along these lines, people have asked how WinJS.Class.define relate to the class structures of TypeScript. When all is said and done, they accomplish the same things. In fact, you can derive WinJS classes from TypeScript classes and vice-versa.

The one exception is that call to WinJS.Utilities.markSupportedForProcessing in WinJS. This is a requirement for functions that are used from other parts of WinJS (see Chapter 4 of my book, pages 145-146) and is the only “hidden” benefit. If you use TypeScript or other libraries to create classes, you’ll need to call that function directly.

In Part 2 of this topic, we’ll look at WinJS.Class.derive. In Part 3 we’ll finish up with WinJS.Class.mix and the idea of mixins.


Section 6.5 of the Windows Store Certification Requirements (v4.0) reads as follows:

You must localize your app for all languages that it supports
Your app can only support Windows Store allowable languages, and at least one of those languages must be a certification language. The experience provided by an app must be reasonably similar in all languages that it supports.

You must provide a complete description of your app for your customers in each language that you declare in your app’s package. The other elements of your app’s description, such as screenshots, text and promotional images, must be localized. If your app is localized such that some features are not available in a localized version, you must clearly state or display the limits of localization in the app description.

It’s important in this context to follow the links to the Choosing your languages topic and clearly understand what is an allowable language and what is a certification language. To quote that topic:

  • Certification languages—the languages that we support when confirming that your app meets our certification requirements. Your app must support at least one of these languages.

  • Allowable languages—languages that we support but do not use as part of the certification process. Your app can support as many of these languages as you like, as long as it supports at least one of the certification languages.

What this means is that if you clearly support one certification language (and there are many), you can then check off any number of the allowable language when you submit your app. If you want to check more than one certification language, on the other hand, then you must make sure that your app is localized for that language and you also provide localized descriptions and screen shots when you submit. This is all so the Store can show that app in a regional market with all that language support in place.

Though I haven’t found it written anywhere, I would also suggest that your make your privacy policy (see Tip #2), if needed, available in each certification language as well.

In short, be very cautious about checking certification language when you submit, making sure that you’re done all the necessary localization work and testing in your app for that language. It’s better to make your first submission with one or just a few languages at first, then add updates later, than to be over-ambitious and fail certification in your major markets because you neglected a detail for a secondary one.


A long time ago this question came up within my team at Microsoft, long before we did any public disclosure of the new system. Before Windows 8, there was really only one choice to write a native app without taking a dependency on an external framework or other middleware of some kind: C++ (or C) with UI layers like WinForms or DirectX. Windows 8, however, introduced other choices for native Windows Store apps, by which I mean one that has direct access to the system's API without relying on middleware to expose it (and thus require that middleware to be updated to take advantage of new system features). Those choices include using JavaScript with HTML/CSS as the presentation layer; using C#, Visual Basic, or C++ with XAML as the presentation layer; or going the C++ and DirectX route.

Early on, I remember people saying "Of course, JavaScript is the easiest language, so that would typically the natural choice." Well, JavaScript might be more forgiving in the beginning, and perhaps easier to get started with because of the lack of strong data types, but it soon becomes somewhat odd. For example, dealing with async APIs through promises involves a lot more code (and concern about closures) than using the await keyword in C#/VB. Furthermore, writing an app isn't just about the language, it's also about the presentation layer. Here, if you don't already know HTML and CSS reasonably well, you end up having two different specs with different syntaxes and different paradigms. Is that's necessarily easier? I commented a number of times that no one seems to have written book like  Crockford's JavaScript: The Good Parts for C# or XAML because the bad parts have already been expunged!

There are, of course, a few reasons why you might be forced to use one language/presentation choice over another. Protecting intellectual property is best done in C++, though not foolproof–and for that you can use a mixed-language approach to put more sensitive code into WinRT components written in C++. (It does also seem that better obfuscators for JavaScript are coming along…more on that another time.)

If raw graphics performance is a concern for your app, then going C++/DirectX ends up being your only real choice. Many kinds of apps can be effectively written in the other languages, but in the end, if perf totally matters to you, make the choice early to bypass any extra rendering layers you can (i.e. HTML/CSS and XAML). The team that created the FreshPaint app, for example, did this very early on as they had already implemented their paint/texture physics engine in C++/DirectX so there wasn't any reason to think to use a different language for the rest of the app's structures.

Similarly, if you really need to do multi-threaded work, you'll find that easier to manage all that in C++ and the APIs it has to offer. Trying to do the same with JavaScript workers probably won't give the results you want. C#/VB might work well too depending on your needs, but again, with a mixed-language approach you can put certain parts in components written in C#/VB or C++ and perhaps do outer app framework in HTML/CSS (assuming you don't need to share drawing surfaces, which can't be done from JS at present).

One potential advantage of HTML/CSS/JS is that you can write code that's more portable to other platforms where HTML-based options are available, including the web. This does require that you keep Windows-specific code isolate, in the way that tools like Phonegap/Cordova do, but it's possible. (Not that the Windows Library for JavaScript, WinJS, is already portable–it will use WinRT if it's available, otherwise it uses HTML5 APIs.) That said, options like Xamarin (for C#/XMAL) and Unity (for DirectX/C++) give you similar cross-platform approaches for the other languages.

There are a few cases where Windows 8 doesn't have exact parity between HTML/CSS and XAML, where HTML/CSS has a couple more controls. On the flip side, if you're trying to directly incorporate web content into an app, you have to use an HTML iframe if the content needs HTML5 capabilities like AppCache or LocalStorage, but then if the web site has frame-busting code, you have to use the x-ms-webview element which doesn't have all the HTML5 goodies, which also goes for the The XAML WebView. Clearly this is an area that can be improved, but for now, it's good to know that these limitations can make-or-break your language decision.

Clearly, if you have existing code in one language or another, then it makes sense to reuse much of that instead of porting it to another language. Once more, this is where a mixed-language approach comes into play.

All in all, the more we discussed this question amongst ourselves, the more we realized that there never really was a set answer for any given developer. We drafted a number of papers to try to spell out the strengths and weaknesses of each choice, but in the end, I whittled it down to these thoughts:

  1. If you already know one of the languages/presentation layers and not the others, and don't have a specific issue that would force you into a choice, then stick with what you know. Otherwise you'll have to face a big learning curve.
  2. If you know more than one of the languages/presentation layers already, then you don't need Microsoft to spell out the strengths and weaknesses: you understand those already and can make an intelligent choice.
  3. If you don't know any of them, then you should spend a couple hours working through the basic tutorials of the Windows Developer Center (the "Developing Apps" topics listed here), and see which one you like the best. I have generally figured that those coming from Java and Objective-C would probably pick up C# (or maybe C++) easier than learning the semi-mystical tones of CSS, whereas a web developer would typically find HTML/JS a familiar territory.

I was very glad, in fact, to see that the banners at //Build 2011 in Anaheim were emblazoned with the words "use what you know" where writing apps was concerned. An in working with partners building apps over the last year, that's pretty much played out to be the right way to approach the matter.

 


HTML5 includes facilities for client-side “web storage” from within JavaScript as a great improvement over cookies. For reference, see http://en.wikipedia.org/wiki/DOM_storage for an overview, http://www.w3.org/TR/webstorage/ for the spec. In Windows Store apps written in HTML/CSS/JavaScript, these features overlap with the application storage APIs in WinRT. In this article I’ll compare and contrast the two.

Note: one key difference for any comparison with WinRT APIs is that HTML and native JavaScript APIs are available in the web context whereas WinRT is not. This comparison therefore only applies to pages running in the local context. In the web context you must use the HTML5/JS APIs.

It’s also helpful to note that overlaps such as these exist (a) because of the local and web contexts, and (b) to provide the capability to Windows Store apps written in other languages where an intrinsic API is not available.

 

In Web Storage, there is local and session storage that differ in scope and lifetime. Local storage is per-domain and persists after the browser is closed. Session storage is per-page/per-window and is cleaned up when the window is closed. If you have multiple windows open with the same site, the benefit here is that session storage is kept separate.

The storage itself is an associative array of strings at present; there is a proposal spec for structured data.

Two such associative arrays are made available in JavaScript: localStorage and sessionStorage. You can create any property in them you want, and retrieve them as you want (checking for existence first, of course):

if (sessionStorage.insurance) { … }

if (!localStorage.pageLoadCount)
localStorage.pageLoadCount = 0;

localStorage.pageLoadCount += 1;
document.getElementById(‘count’).textContent = localStorage.pageLoadCount;

The WinRT APIs are available through the Windows.Storage.ApplicationData class, which gives you access to StorageFolder objects for Local, Temp, and Roaming areas of AppData along with localSettings and roamingSettings (containers for key-value pairs including sub-containers). The Application object in the Windows Library for JavaScript (WinJS) also contains a local, temp, and roaming objectsto simplify working with the ApplicationData APIs (it also has a sessionState object into which you can write values, but these are only restored if an app is restarted after being terminated by Windows when freeing up memory). For details, see Chapter 8 of my book (as well as sections of Chapter 3).

Comparing the APIs:

  • HTML5 sessionStorage (per window) in browsers is effectively the same as local variables in an app, because typically you use a single-page navigation model (with DOM replacement) to preserve the script context across pages. From an app’s point of view, then, In other words, sessionStorage is just a global array that had an automatic new done for it. That’s all.
  • WinRT local and HTML5 web local storage both use persistent storage that is available to the app across instances, that is, if the app runs and writes to local storage, is then closed by the user, then restarted, the local storage values are persistent.
  • HTML5 web storage has only a simple array model with strings. WinRT is much richer, with type-specific settings, hierarchical containers, composite settings (groups of settings that act as a single unit), and also supports unstructured (binary) data in arbitrary files. You’d have to encode binary data into text for web storage.
  • Web storage works on a synchronous model; WinRT is synchronous for settings, asynchronous for files.
  • WinRT and HTML5 storage are both kept in the user’s AppDatapackages<package> folder and is automatically cleaned up when the app is uninstalled.
  • WinRT supports automatic roaming through the RoamingSettings container and Roaming folder (up to 100K total data); HTML5 web storage is entirely local.
  • WinRT supports a temp folder that can be cleaned out with the Disk Cleanup tool. This makes a great place for caching data that can be restored at another time.

 

For small bits of data, an app might use HTML storage for the sake of simplicity if you’re familiar with the API. However, it means having a different (and UI-thread blocking) programming model from the roaming settings and a lack of unstructured data (file) capability. One also has to watch out for the fact that all the data are a strings and will be handled like strings. So for the code that does the launch count as above (which is pulled from the W3C spec), when you reload the pageLoadCount at a later time, the data type is actually a string, and adding 1 doesn’t increment the value, it appends “1” to the string. You have to do a parseInt on the value from localStorage to get a numerical value again.

The other comparison to make between these methods is to review the storage limits imposed by each mechanism, as summarized in the following table. For completeness, we’ve also included other storage HTML5 mechanisms like IndexedDB and AppCache as these also employ the app’s AppData area on the file system.

Storage Method Limit (up to file system capacity)
Web storage (local) 10MB
Web storage (session) 10MB
WinRT localSettings
(structured settings)
  • 8K per individual setting (1)
  • 64K per composite setting (1)
  • No limit on overall settings
WinRT localFolder
(unstructured files)
None
WinRT roamingSettings
(structured settings)
  • 8K per individual setting (1)
  • 64K per composite setting (1)
  • No limit on overall settings. Exception:   sync engine may limit total amount of roamingSettings and roamingFolder   data that will roam (2)
WinRT roamingFolder
(unstructured files)
No storage limit. However, the sync engine limits total the   amount of roamingSettings and roamingFolder data that will   actually roam. (2)
WinRT tempFolder
(unstructured files)
None (3)
Cookies 4K per cookie; no limit on total cookies
History None
Temporary Internet Files None (4)
IndexedDB 250MB per app, 12.5% of overall storage or 1TB, whichever is   less.
HTML5 Appcache None (4)

 

(1)    These are arbitrary limits and may change.

(2)    The default sync engine presently imposes a 100K limit (see the roamingStorageQuota property); if the combined contents of the roamingSettings and roamingFolder exceed that limit, the settings will still only be stored locally and no data is roamed. Again, this is a limit of the sync engine: the WinRT APIs themselves don’t impose limits. Different sync engines can behave differently.

(3)    Files created in the tempFolder are subject to deletion by Windows’ Disk Cleanup utility.

(4)    Current design with Windows Store apps does not impose a storage limit for AppCache (along with any other cached files from the web); IE will continue to enforce user- and system-defined limits.

 

In the end, if you’re writing new code, I recommend using the WinRT APIs to have a consistent async programming model across local, roaming, and temp data. If you have existing code that uses HTML5 web storage, it will continue to work subject to the limits outlined above.