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()).

 


A partner we worked with had some troubles with a live tile image not appearing, and the process of working them out helped us understand better how to debug live tile issues.

First of all, make sure of two more global that affects tiles:

  • Live tiles don't appear in the Visual Studio simulator for Windows Store apps (though I believe they do on the phone emulator). Run locally or on a real device.
  • Make sure that live tiles for your app on the Start screen are not disabled (right-click to check).
  • Some live tiles won't look right if you've turned off system animations in PC Settings > Ease of Access > Other Options > Play Animations.

Second, the tile updater is quite sensitive to properly-formed XML. If you have any kind of glitch, the update payload will be ignored and you'll be left scratching your head. Here are some things that can trip you up:

  • The XML lacks the <?xml version="1.0" encoding="utf-8"?> header.
  • There is a space or linefeed before the <?xml> header.
  • The XML isn't properly formed (e.g. missing closing tags) or doesn't follow the Tile schema.
  • The elements you indicate for a tile template doesn't match the template itself.
  • You have a mismatch between the indicated template and the version number in the <visual> element.
  • You are using accidentally using <img> tags rather than <image> in the XML. Tile templates are not HTML: they use <image>.

If you think your XML is good but it's not working, try simplifying it to include only a single tile size payload, and try them one at a time. That can narrow down where an issue might be. Also use App Tiles and Badges sample as a reference point, specifically scenario 6 that lets you build payloads.

Next, a tile update can have proper XML but its image references might be invalid. If you're using http[s] references, double-check those links in a browser. If you're using the baseUri attribute anywhere in your XML, do that combining manually and check the URIs. Also check image references with any URI parameters that are added with the addImageQuery attributes. See "Using Local and Web Images" in Chapter 16 of my free ebook (page 897) for details.

Other allowed reference URI schemas are ms-appx:/// and ms-appdata:///local. You cannot use ms-appx-web:/// or ms-appdata:///[temp | roaming] — doing so will cause the update to be ignored.

Thirdly, remember that tile images must be 1024 pixels or less in both dimensions, and must be less than 200KB in size. This means potentially resampling an image to make it smaller, and it especially means being aware of the image format and quality as that significantly affects the size. Here's how I wrote about this issue in my book, page 899:

Sidebar: PNG vs. JPEG Image Sizes

When considering tile images for the larger 140% and 180% scales, the encoding you use for your images can make a big difference and keep them below the 200K size limit. As we saw in “Branding Your App 101” in Chapter 3, a wide tile at 180% is 558×270 pixels, a medium is 270×270 pixels, and a large is 558×558 pixels. With the wide and large tile sizes, a typical photographic PNG at this size will easily exceed 200K. I encountered this when first adding tile support to Here My Am! for this chapter, where it makes a smaller version of the current photo in the local appdata folder and uses ms-appdata:///local URIs in the tile XML payload. Originally the app was capturing PNG files that were too large, so I borrowed code from scenario 11 of the App tiles and badges sample, as we’ve been working with here, to create a smaller PNG from the img element using a temporary canvas and the blob APIs. This worked fine for a 270×270 medium tile image (a 180% scale that can be downsized), but for 558×270 and 558×558 the file was too large. So I borrowed code from scenario 3 of the Simple Imaging sample to directly transcode the StorageFile for the current image into a JPEG, where the compression is much better and we don’t need to use the canvas. For this second edition’s example I just capture JPEGs to begin with, which are already small enough, but I’ve preserved the code anyway for reference. You can find it in the transcodeImageFile function in pages/home/home.js, a routine that we’ll also rewrite in Chapter 18 using C# in a WinRT component. 


Such considerations are certainly important for services that handle the addImageQuery parameters for scale. For larger image sizes, it’s probably wise to stick with the JPEG format to avoid going over the 200K limit. 

 

The 200KB limit turned out to be the issue with the partner–all the images referenced in the live tile were larger than 200KB and therefore ignored. More specifically, the images were saved as PNGs, which again for photographic images produces larger file sizes than JPG. In this partner's case, even the 150×150 tile image was too large; if it had happened to be smaller, the partner would have seen it appear but not images for the other sizes, which might have revealed the problem more quickly.

What confused the process of tracking down this problem is that an invalid image will cause that particular tile update (for that size) to be ignore in toto, meaning that the text won't appear with an invalid image. This is a reasonable behavior because otherwise end users would see oddball tile updates with text but blank spots where images should be. Personally I'd love to see a debug option in the system that you could turn on so some kind of placeholder image would appear, or an error message if a tile update is invalid.

The other thing that can be confusing is that the system will always download an image from a valid URI, and then check whether it's too large to display. This makes some sense as it's difficult to know from a URI whether the image is too big or such. The system could do a round-trip to the network to check the size first and not download it, but it doesn't work that way: it will download, and then ignore the image. This means that just watching fiddler traces or such isn't deterministic in checking image validity.

If you have a service, by the way, that dynamically generates images for periodic tile updates, then it's possible to have some variance in image sizes that are being supplied in tile updates. For debugging, make sure your service is logging requests and the dimensions and file size of every image returned. Then you can see whether any images exceeded the allowable limits.


In a number of forum questions over the years, I've seen devs struggling with using relative URIs to in-package resources. Typically it boisl down to the difference between something like "images/pix1.jpg" and "/images/pix1.jpg".

These two URIs mean, in the words of Jeremy Foster, "dive into the images folder and find pix1.jpg" and "go back to the root, then dive into the images folder and find pix1.jpg", respectively.

In Windows Store apps, it's helpful to remember that all such in-package 'relative' URIs are shorthands for ms-appx://<package_id>, as in ms-appx://<package_id>/images/pix1.jpg or just ms-appx:///images/pix1.jpg. A leading / on URIs, then, is what really makes the reference an absolute one, rather than a relative one. It just feels relative because you're not specifying a schema.

To be even more precise, a relative URI always must resolve against some base URI, which is defined by the referring document. Where people get tripped up is that when you're using WinJS page controls, such as ms-appx:///pages/somePage.html, then ms-appx:///pages becomes the base URI, and images/pix1.jpg will resolve to ms-appx:///pages/images/pix1.jpg. If you thought you were referring to the root images folder in the project, then you'll likely find the image not appearing at all. If you use /images/pix1.jpg, on the other hand, then you are making an absolute reference from the package root via shorthand, which resolves to ms-appx:///images/pix1.jpg.

The bottom line is that unless you really know that you're making a relative reference to the currently loaded HTML page, use a leading / to get back to your package root.


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

 


When creating apps for both Windows 8.1 and Windows Phone 8.1, you typically want roaming data–as managed through the WinRT APIs–to work seamlessly across both.

The first requirement here is that both apps are using the WinRT APIs for this purpose, meaning that the Phone app project is not using Silverlight but rather the "Windows XAML" or WinRT flavor. Clearly this isn't an issue for apps written in JavaScript, where that's the only option, nor for universal Windows apps that focus on WinRT.

Note that it's not necessary to implement the app with a universal app project in Visual Studio. Those project structures are simply a way to simplify development processes, and isn't a requirement for providing the same app experience on both Windows and Windows Phone.

The second requirement, however, is that both apps–however you build them–must have the same identify in their respective stores, which means specifically the package family name. This is what's used to manage the roaming settings, and so long as those match, then both implementations will work with the same roaming data. This is again a given with a universal app project, but something you have to do manually if implementing the apps with separate (non-universal) projects.

A little guidance on this can be found here: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/dn630421.aspx

For some general Q&A on app data, which includes other aspects of roaming, see my post on the Building Apps for Windows blog: http://blogs.windows.com/buildingapps/2014/06/19/common-questions-and-answers-about-files-and-app-data-part-1-app-data/


Some Q&A I've collected recently. Enjoy.
 

Q: I'm trying to bind part of a ListView item template to the result of a method in a class, but the function text itself is appearing instead of the result. How can I make this work?

A. Here's the context for the question. Say we have a simple binding declaration as follows:

<div data-win-bind="textContext: FullName"></div>

And we're binding to a class that looks like this:

var _MyClass = WinJS.Class.define(
    function () {
        this.FirstName = "";
        this.LastName = "";
    },
    {
        FirstName: "",
        LastName: "",
        FullName: function () {
            return this.FirstName + ' ' + this.LastName;
        }
    }
);

The issue is that binding to FullName doesn't execute the function, but just binds to the function object. There aren't problems binding to FirstName and LastName as those are just properties.

The solution here is to make FullName a property as well, rather than a function, which can be done as follows:

FullName: {
    get: {
        return this.FirstName + “ “ + this.LastName;
    }
}

[Thanks to Dominic Hopton]

 

Q. Is it possible from JavaScript to bind to data in a WinRT component?

A. Yes. The trick is that you need to use WinJS.Binding.oneTime as the initializer in the binding syntax. For a full discussion, see Mike Taulty's blog: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2012/04/26/windows-8-metro-style-bits-of-binding.aspx

 

Q. Is it possible to use WinJS data binding on styles and other non-text elements?

A. Yes it is. In general you can use the syntax data-win-bind="style.<target_property>: <source_property>", and for styles like font-weight and text-decoration that don't work with dot notation you can use []'s as in data-win-bind="style[target-property]: <source_property>".

Phil Japiske has a good post on this subject on Telerik's blog: http://blogs.telerik.com/Windows8Team/posts/13-12-27/setting-html-styles-with-binding-in-windows-8-winjs-apps 


In a previous post I described how to realiably use Debug/Release build configurations in Visual Studio to selectively copy a debug or release file into your project at build time, offering a solution to JavaScript's lack of precomiler directives like #ifdef DEBUG as found in C# and C++. I wanted to expand on that post with additional options that I've seen discussed. [Thanks to Rob Paveza, Ginger Edighoffer, Howard Kapustein, Steve Bohlen, and Gearard Boland.]

In this context, people often suggest using the following structure for similar purposes:

if (Debug.debuggerEnabled) {
    // use debug settings
}
else {
    // use production
}

Although this works reasonably well, the downside is that having a debugger enabled says nothing about how the project was built. You can debug a Release build of a JavaScript app just fine, in which case debuggerEnabled will be true and you can still step through the code because JavaScript isn't compiled ahead of time. This means that stepping through the code above for a Release build will not hit the //use production block.

You can work around this, of course, by setting a breakpoint on the if statement and then setting the next statement to the //use production block. If you want to do this pervasively, then you can wrap a simple function around Debug.debuggerEnabled where you can set a single breakpoint:

function checkDebug() {
    if (Debug.debuggerEnabled) {
        return true;
    } else {
        return false;
    }
}

In here I've put in two return statements so there's an obvious place to set the next statement and control the return value.

Another suggestion I've seen for this matter is to create a simple C++ WinRT component that does something like this:

namespace WrcCpp
{
    public ref class ModeMonitor sealed
    {
        private:
            ModeMonitor() { };

        public:
            static property bool IsDebugMode {
                bool get() {
#ifdef _DEBUG
                    return true;
#else
                    return false;
#endif
                }
            }
    };
}

There's also a property in Windows.ApplicationModel.Package.current.isDevelopmentMode that you might come across but this reflects how the package was installed (that is, it was deployed from Visual Studio rather than the Store), and not how the package was built. That is, it describes the deployment mode, not the build target.

Here's another possibility: run your JavaScript code through a C++ preprocessor that can chew on the #ifdef statements to generate the JavaScript code you want to run. I imagine that this could be incorporated into a Visual Studio build process similar to my previous post. 

Along these same lines is the need to differentiate code in a universal Windows app project that's targeted specifically to Windows or Windows Phone when that code lives in the Shared folder. That is, although you can keep code for both targets separate in their own project structures, sometimes it's just easier to make a simple differentiation within some of the Shared code.

The compiled languages have the WINDOWS_APP and WINDOWS_PHONE_APP precompiler directives for this purpose, but not JavaScript. The options you have, then, are as follows [thanks to Steve Bohlen]. First is WinJS.Utilities.isPhone:

if (WinJS.Utilities.isPhone){
    // phone
}
else{
    // not phone
}

Second is using a feature detection pattern like you do with cross-browser JavaScript:

if (PhoneAPINamespace && PhoneAPINamespace.phoneAPI) {
   //  safely call phoneAPI()
}

The first option is more explicit, of course, whereas the second is more resiliant to changes in the available API (a consideration with continued convergence in WinRT).

 


I've seen a report where adding a Windows Phone 8.1 to an existing app project caused files added to the shared project to be dropped in the project root rather than the folder hierarchy of the shared project. (This doesn't happen with new projects, by the way.)

To be specific, say you have an existing Windows 8.1 app project. You right click on that and select the "Add Windows Phone 8.1" command, which creates a Phone project and a Shared folder in your solution.

If you encounter this, the workaround is to open the project files manually (unload and edit in VS, or edit in Notepad), and make sure the <Import> tags in the project put the shared project first. That is:

<Import Project="..App2.SharedApp2.Shared.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)MicrosoftVisualStudiov$(VisualStudioVersion)$(WMSJSProjectDirectory)Microsoft.VisualStudio.$(WMSJSProject).targets" />

 


In case you haven't noticed, a recent update to Windows 8.1 makes a Privacy Policy link recently appear autmatically for Windows Store apps. This link takes the user to the app's page in the Store where the privacy policy link is available.

This means that apps no longer need to include their own privacy link; however, I don't yet know how to detect whether this is happening for an app so you can suppress your own link.If anyone has investigated this, please post in comments. That said, I personally like having a cleaner Privacy Statement link in an app that can open a settings pane directly with that content, rather than navigate to the Store.

It's worth noting that with this change, all you have to do to meet requirement 4.1.1 of the Store Certification Policy is submit a link to your policy when you submit the app. Because the app cert testers will be using the latest 8.1 build, you should pass cert without having a distinct command in your own settings.