My associate Brian Rasmussen released this book through Microsoft Press a few months ago: http://www.amazon.com/High-Performance-Windows-Store-Brian-Rasmussen/dp/0735682631/ref=sr_1_1?s=books&ie=UTF8&qid=1414429701&sr=1-1.

Here's the short review I wrote on Amazon:

Performance is something that's easy to talk about but difficult to do. You could say that every app could in some way perform better, but how do you really think about where to make investments? Too often, developers take an ad hoc approach, not really clear on what they're trying to accomplish. This can waste a lot of resources in areas that won't have real impact on the customer experience. In this book Brian brings years of real-world insight to the question of finding what matters, clearly defining your performance goals, and then going through the process to measure the app's present reality, making changes, and evaluating progress. And like another reviewer has said, performance information–even just what tools are available–is scattered around, and having one place to bring it all together is super-valuable. 

At 240 pages it's a concise treatment of the subject and for the price (Amazon has it at $14.13), it only takes one or two good improvements to your app to more than pay for itself!


From a background task, it's perfectly allowable to issue a tile update, for instance, when procedding a raw push notification in that task and updating a tile in response. With secondary tiles, you might also want to update the tile's arguments so that it launches into different content relevant to the tile update. However, secondary tile arguments are statically defined when the tile is pinned and cannot be changed later.

To work around this, you can use a set of static identifiers that you then dynamically map to your variable data. It's simplest to just keep a table of secondary tile IDs mapped to their dynamic arguments, in which case you're probably not using the static arguments at all.

Another question with background tasks is whether it's possible to do file I/O therein, because clearly if you're modifying a table of secondary tile arguments in a file you'll be doing file I/O. The thing to remember here is that if you use any kind of async APIs in the process, you need to make sure the background task stays active until the async work is complete. To do this, you use the deferral mechanism.

In C#, the general pattern is like this:

public async void Run(IBackgroundTaskInstance taskInstance)
{
    var deferral = taskInstance.GetDeferral();
    var contents = await DoAsyncWork();
    deferral.Complete();
}

In JavaScript, the deferral is found on the WebUIBackgroundTaskRuntimeClass object. You retrieve this in the worker with Windows.UI.WebUI.WebUIBackgroundTaskInstance.current, then call its getDeferral method, do your async work, and then call the deferral's completed method when you're done.

var task = Windows.UI.WebUI.WebUIBackgroundTaskInstance.current;
ver deferral = task.getDeferral();

DoWorkAsync().done(function () {
    deferral.completed();
    close();  //Shut down the background task
});

Note that JavaScript it's also necessary to call close() when the task is finished (which is WorkerGlobalScope.close()).

 


When I was writing the last chapter of Programming Windows Store Apps with HTML, CSS, and JavaScript, 2nd Edition, I noticed that when you used the CurrentAppSimulator object for testing the Store APIs, that the default XML included a bit for consumable in-app purchases:

<ConsumableInformation>
  <Product ProductId="2" TransactionId="00000000-0000-0000-0000-000000000000"
      Status="Active" />
</ConsumableInformation>

Unfortunately, it wasn't documented, so I had to work it out with the program manager who owned it. Put simply, the ConsumableInformation is used to provision a default in-app offer similar to how durable offers are included in the LicenseInformation node.

The TransactionId attribute is required, and will match the value used when calling CurrentAppSimulator.ReportConsumableFulfillmentAsync(productId, transactionId).

Status is also required, and can be Active, PurchaseRevoked, PurchasePending, and ServerError. This allows a developer to emulate all the possible responses to the ReportConsumableFulfillmentAsync call.

There is an optional attribute OfferId on the <Product> element which can be used to set the same value that would normally be set at the time of purchase for the large catalog API: CurrentAppSimulator.RequestProductPurchaseAsync(productId, offerId, displayProperties).

Fortunately, we were able to get all this into the CurrentAppSimulator documentation, which you can find here: http://msdn.microsoft.com/en-us/library/windows/apps/windows.applicationmodel.store.currentappsimulator.aspx

 


[For full details on working with the Windows Store, see Chapter 20 of my free ebook Programming Windows Store Apps with HTML, CSS, and JavaScript.]
 

For this final post, I wanted to provide the list of ms-windows-store URIs that you can launch for various purposes (using Windows.System.Launcher.LaunchUriAsync). These are in my book, but are good to have as a blog post:

  • ms-windows-store:PDP?PFN=<package_family_name> links directly to the app’s page; the package family name is what comes back from Windows.ApplicationModel.Package.current.id.familyName.
  • ms-windows-store:REVIEW?PFN=<package_family_name> goes to the Ratings and Reviews section of the Store for your app, which is what the Rate And Review command in your Settings pane does. You can launch this URI from your app directly when inviting a review. Note, however, that there is not presently a means to determine whether the user left a rating or review.
  • ms-windows-store:Publisher?name=<publisher_display_name> Links to a page that shows all your apps, which you might do from an About pane in your Settings. The publisher name can be from Package.current.id.publisher.
  • ms-windows-store:Updates opens the Store’s updates page (no arguments). You can use this when you detect that the user is running an older version
  • of your app, which suggest they’ve opted out of auto-updates.
  • ms-windows-store:Search?query=<search_string> executes a search in the Store.

[For full details on working with the Windows Store, see Chapter 20 of my free ebook Programming Windows Store Apps with HTML, CSS, and JavaScript. Note also that CurrentApp refers to Windows.ApplicationModel.Store.CurrentApp for convenience.]
 

Q. Why does CurrentApp.GetProductReceiptAsync return a not implemented exception for a Windows Store app?

A. This API is not implemented for Windows, just for Windows Phone. Windows Store apps should use the CurrentApp.GetAppReceiptAsync API and examine the in-app purchase receipts contained within it. (In short, this is one area of non-convergence with universal Windows apps at present.) 

 

Q. Can an trial version of an app provide in-app purchases?

A. No, by design the CurrentApp.RequestProductPurchaseAsync API does not work when the app is running under a trial license if the app is paid. The API can be invoked, but will fail. However, if the app is free, then in-app purchases will work (see the next question).

This is important to understand when testing an app with the CurrentAppSimulator: by default, the simulator assumes a trial version, so CurrentAppSimulator.LicenseInformation.isTrial will be true and in-app purchases won't work. To fix this, make sure your WindowsStoreProxy.xml file contains the following:

<LicenseInformation>
  <App>
    <IsActive>true</IsActive>
    <IsTrial>false</IsTrial>
  </App>
  …
</LicenseInformation>

Q. I have a free trial app in the Windows Store with features that turn on when the full app is purchased. Can I change this to a free app (no trial) with in-app purchases?

A. Then question here is reall about handling the transition between licensing states, that is the information provided by CurrentApp.LicenseInformation. Prior to the app update, you'll have users with two possible states with the desired transition logic:

  • LicenseInformation.isTrial= true : convert to non-trial (full) version with no-in app purchases
  • LicenseInformation.isTrial = false : turn on licenses for in-app purchases that match the paid version.

When the update happens, it's important to note that the trial state of the all (isTrial) will continue to be true, but because the app is now free, in-app purchases will work properly. In this case, then, the app wouldn't bother to make any differentiations between trial and non-trial; that is, the updated app wouldn't ever check the isTrial flag at all.

The trick is then differentiating new installs of the app, which will have isTrial = false and isActive = true, from those who previously purchased the app and for whom these flags have the same values. You'll need another mechanism, then, other than the LicenseInformation itself, to differentiate the upgrades. 

This is straightforward to do. The best way is to CurrentApp.GetAppReceiptAsync to retrieve the app purchase receipt and check the receipt date against when you made the conversion. Any customers who purchases the app prior to that date were ones who paid for the license and should thus be granted all the rights that you otherwise now only grant through in-app purchases. Thus in your code to enable features, you would check that either (a) the appropriate in-app purchase license is set or (b) a previous purchase was made.

 

Q. I'm having trouble getting my licensing logic to work correctly; what's the best practice for checking license states?

A. The most reliable place to put your licensing logic is inside a handler for CurrentApp.LicenseInformation.LicenseChanged event. If you consolidate everything here, then you naturally handle any change made through purchase APIs, as well as trial expirations and other license-affecting events. You can check specific license flags after one of the async purchasing APIs completes, but as those should invoke LicenseChanged it's much cleaner to keep everything in the event handler.


I have a few bits related to the Windows Store and apps that I thought I'd share this week and next as a kind of Q&A. (And if you're curious why I like Q&A formats, it's because I collect a lot of answers from developer questions I see on different forums, and then consolidate related ones here.)

[For full details on working with the Windows Store, see Chapter 20 of my free ebook Programming Windows Store Apps with HTML, CSS, and JavaScript.]

 

Q: Is there a way to persist unique data for an app after it's uninstalled? Put another way, how can an app save a piece of data (like an ID) so that it knows it was previously installed on a particular device?

A: Some background first. As you might already know, when a Windows Store/Phone app is uninstalled, all of its app data is also uninstalled. Roaming data lives on in the cloud for a time even if the app is uninstalled from all of the user's devices, but nothing remains on the device itself. So you can use roaming data for the purpose in the question, but after some time (like 30 days) the roaming data might disappear. Roaming data, in other words, is reliable only if you want to save user-specific data so long as the app is installed on at least one device.

Although you could consider saving something as user data–which would require asking the user to pick a location through the file picker–that would be clumsy and end up polluting user data areas with stuff that doesn't make sense to the user directly.

The only alternative, then, is to store that data in the cloud (a table within Azure Mobile Services comes to mind here) indexed by some kind of per-user app-specific identifier so it can be precisely retrieved later on. (This is, in fact, the scenario that prompted the question: the developer wanted some unique ID for a guest account to which to associate in-app purchases that did not go through the Store itself.) This leads to the next question.

 

Q: Where can I get a unique per-user per-app identifier that's unique across devices for the same user? And what about a device-specific identifier?

A: There are good answers to both of these questions. For the latter, a device-specific ID, also know as an App Specific Hardware ID (ASHWID), ca be obtained from the Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken method (Windows 8 and Windows Phone 8.1; for Windows Phone 8, try HostInformation.PublisherHostId). For additional details on this API, refer to also Guidance on using the App Specific Hardware ID (ASHWID) to implement per-device app logic.

OK, that was easy–what about a per-user ID? For this one, use the App Receipt ID available through the Windows Store API, namely Windows.ApplicationModel.Store.CurrentApp.GetReceiptAsync. This returns you a piece of XML from which you'll need to parse the AppReceipt > Id property, a process that's straightforward with the XmlDocument class in WinRT:

Windows.ApplicationModel.Store.CurrentApp.getAppReceiptAsync().done(function (receipt) {
    var doc = new Windows.Data.Xml.Dom.XmlDocument();
    doc.loadXml(receipt);
    var appReceipt = doc.getElementsByTagName("AppReceipt");

    if (appReceipt != null && appReceipt[0] != null) {
        console.log("AppReceipt.Id = " + appReceipt[0].getAttribute("Id"));
    }
});

Again, the AppReceipt ID will be unique per user across all installations on all devices, which includes universal Windows apps in Windows and Windows Phone where those apps share the same package family name.  

Remember that the ASHWID is unique for a device, but not for multiple users of that device, so if you want a per-user and per-device ID, you'll need to combine the user-specific ID from the app receipt and the ASHWID.

 

Q; Speaking of uninstallation, are old versions of an app still available in the Store? That is, if I uninstall and app and then it gets updated in the meantime, can I install the version I previously had?

A: No, only the current version of an app is maintained in the Store. If you uninstall and reinstall, you'll get the latest version.



A question on the MSDN JavaScript apps forum recently asked why the app data APIs were in Windows.Storage.ApplicationData whereas the app's package folder property is off in Windows.ApplicationModel.Package. I responded with the following comments, which Howard Kapustein confirmed (he did much of this wrangling early on).

I don't know the exact history (this would've been taking place in early 2011) but I imagine it could've gone either way and someone eventually had to make a decision. Generally speaking, Windows.ApplicationModel has package information along with a bunch of APIs that deal with app-to-app communication, contracts, activation, suspend/resume, and background tasks. Windows.Storage, on the other hand, has everything to do with the file system.

Because appdata folders are probably more closely aligned with the file system than with the "app model" stuff, I can see why Windows.Storage was the landing place. After all, that's where you find all the other file I/O APIs, and I can imagine that if the ApplicationData APIs were in Windows.ApplicationModel, we'd be having the same question about why they weren't in Windows.Storage. 🙂

I would guess that there was probably an argument for putting the package information classes into Windows.Management.Deployment, which is probably it's most natural home. However, the rest of the APIs there are desktop-only and not accessible to Store apps, so it made some sense to put the Package class elsewhere. I expect this decision was probably made well after the decision to put ApplicationData into Windows.Storage.

It's also worth noting that the appdata folders are not technically part of the package, so it's really the installedLocation property that's the aberration. The rest of the Package and PackageId properties come from the Store and describes the package characteristics more than runtime state. Thus installedLocation just so happens to be the link between all the package info and the file system.

In the end, I think the structure that we have actually makes the most sense, because when you start talking about appdata you automatically end up in Windows.Storage.

Knowing the guys in API naming team that bandied all this kind of stuff about (guys like Harry Pierson, Jason Olson, and Brent Rector–and now I can add Howard Kapustein as well), I expect that they discussed all these pros and cons before making a decision. Howard describes it as "sausage making" if you want a great visual image!


With the introduction of universal Windows apps at //build 2014, and the announcement of Windows Phone 8.1 that includes support for writing apps in HTML, CSS, and JavaScript, we do have some resources that are starting to emerge.

First, my newly-released second edition, http://aka.ms/BrockschmidtBook2, is very applicable to Phone apps. I didn't have time to spell out all the differences, but there is a summary of what to watch out for in Chapter 1, namely a few differences in controls and some parts of WinRT that aren't on the Phone.

Second, watch the Building Apps for Windows Blog for material in this area. For example, an upcoming post will spell out the controls story between Windows (WinJS 2.0) and Windows Phone (WinJS 2.1).

Third, Josh Williams and Ryan Salva did a demo session on building a universal app with HTML, CSS, and JavaScript at //build, which you can find on http://channel9.msdn.com/Events/Build/2014/2-540. What you'll see is that they do nearly all of the work in the Shared folder of the VS project, making only one small change at the end of the session to switch the Hub control in the Windows Store app to Pivot in the Phone app…the two controls, in fact, are identical in their API except for the top-level object names, so you just change the names and voila! You're in business.

Finally, there is a post on the Visual Studio blog on universal apps: http://blogs.msdn.com/b/visualstudio/archive/2014/04/08/building-windows-phone-8-1-apps-in-html.aspx.

More is certainly to come.


I ran into this alongside the findAllAsync trouble I was having in the previous post. To be more specific, I've been converting a small sample that's in the ZIP file for //build 2013 session 3-026 (http://channel9.msdn.com/Events/Build/2013/3-026, the ZIP is http://files.channel9.msdn.com/thumbnail/f9025b07-120c-4320-8de6-a5de2d255b7c.zip) . This is a C# sample to talk to a Sphero device using the Windows 8.1 Bluetooth.Rfcomm API.

The problem I was having was that write.storeAsync (write is a Windows.Storage.Streams.DataWriter object) was throwing an exception, hence my try/catch block:

function changeColor() {
    output.innerText = "";

    if (writer == null) {
        return;
    }

    var packet = generateRandomColorPacket();
    writer.writeBytes(packet);

    try { 
        writer.storeAsync().done(function () {
        }, function (e) {
            output.innerText = "Failed to write packet; " + e;
        });
    } catch (e) {
        output.innerText = "DataWriter.storeAsync failed (exception); " + e;
    }
}

The exception message wasn't at all helpful: it just said: "The operation identifier is not valid." Huh?

With the help of some colleagues in the Bluetooth team who looked this over, we found a small glitch in the code below that opens the socket to the device. Do you see the error?

function openSocket() {
    output.innerText = "";

    if (device == null) {
        return;
    }

    // Create a socket and connect to the target
    var sockNS = Windows.Networking.Sockets;
    socket = new sockNS.StreamSocket();
    socket.connectAsync(device.connectionHostName, device.connectionServiceName,
        sockNS.SocketProtectionLevel.bluetoothEncryptionAllowNullAuthentication)
        .done(function () {
            writer = new Windows.Storage.Streams.DataWriter(socket.OutputStream);
        }, function (e) {
            output.innerText = "Failed to open socket; " + e;
        });
}

Don't feel bad if you missed it, because I did. It's this line here, which I'd brought over from the C# code. Now do you see the problem?

writer = new Windows.Storage.Streams.DataWriter(socket.OutputStream);

It's hard to see: socket.OutputStream should be socket.outputStream! In other words, I was creating a DataWriter with undefined rather than the real stream. DataWriter didn't complain, though, until it tried to access the backing stream via storeAsync.

Changing that one character solved the problem.