I've had the services below running for a few years to support Programming Windows Store Apps with HTML, CSS, and JavaScript. Hwoever, given that the books themselves are getting a bit out of date, I figured it's time to shut them down. Using the examples in the books, similar services would be easy enough for you to deploy to a host of your own. Let me know if you have questions.

http://programmingwin-js-ams.azure-mobile.net

http://programmingwin8-js-ch13-amspushnotifications.azure-mobile.net

http://programmingwin8-js-ch13-hellotiles.azurewebsites.net

 

 


If you're finding Visual Studio complaining about an expired certificate when building a Cordova project for a Windows target, this is a known issue because the certificate that's checked into the Cordova source tree expired on 11/11/2014. See http://msopentech.com/blog/2014/11/11/cordova-certificate-issue-were-working-on-it/ for details and workarounds.


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.]

 

Q. I want to have my app load and show in-app purchase listings, but until the app is in the Store, such listing information won't be available. As a result, my app will look non-functional and could fail certification. What can I do about that?

A. The right approach is to remember that Windows.ApplicationModel.Store.CurrentApp.LoadListingInformationAsync is not ever guaranteed to work. Having no listing information in the Store is one case where it would fail, but so is lacking connectivity. Therefore you should always write your code to fail gracefully is no in-app purchase listings can be obtained. Arik Cohen of the Store team suggests these approaches:

  • Manage your list of in-app purchases in your own service (or have the list built into the app) and use the ListingInformation only for pricing.
  • Don't show the prices within your app
  • Show the purchases as presently unavailable and suggest the user checks back later.

Know too that the unavailability of ListingInformation doesn’t mean that you don’t have in-app purchase information; CurrentApp.LicenseInformation maintains a local cache of all durable in-app purchases that the user has made.

Gracefully handling the case when you're unable to retrieve in-app purchase listing information should avoid any problems in certification.

 

Q. Is there a way to add or edit in-app purchases to an app that is currently published without having to submit a new build of the app?

A. To change the listing information you always have to submit an update, but you don't have to upload a new app package or change the app's version number. And because you're not changing the package, certification should be quick.

To avoid having to resubmit, you'll need to manage your own in-app purchase catalog, which enables you to generate your list of available purchases dynamically. For more details, see Chapter 20 of (my free ebook) Programming Windows Store Apps with HTML, CSS, and JavaScript, in the section "Handling Large Catalogs" starting on page 1145.


[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.


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.