With the introduction of universal apps for Windows 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 (http://blogs.windows.com/windows/b/buildingapps/default.aspx) 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.


Programming Windows Store Apps with HTML, CSS, and JavaScript, Second Edition, is now released! You can find this free ebook (PDF, Mobi, and epub) it on http://blogs.msdn.com/b/microsoft_press/archive/2014/04/08/free-ebook-programming-windows-store-apps-with-html-css-and-javascript-second-edition.aspx. Companion content is on http://download.microsoft.com/download/6/6/5/665AF7A6-2184-45DC-B9DA-C89185B01937/Programming_Windows_8_Apps_HTML_CSS_JavaScript_2E_CompContent.zip and the videos are on http://microsoftpressbooks.azurewebsites.net/programming_windows_apps_with_html_2ed/.

I have to say that it's ironic that although the book covers Windows 8.1 and is mostly applicable to Windows Phone 8.1 as well, announcements at //build changed the landscape almost immediately. For one, WinJS is now open source and isn't specific to Windows Store Apps, and WinJS 2.1 for Windows Phone has some differences from WinJS 2.0 for Windows Store apps. Oh well. Guess it's onto the third edition now! Still, I suspect that this book, being free and the most comprehensive, will continue to be the primary WinJS reference, open source or not.

 

 


The video of my talk at //build 2014 is online: http://channel9.msdn.com/Events/Build/2014/2-638. "Understanding Customer Patterns: Instrumenting Your App for Telemetry and Analytics." The written version of this is what I published on the App Builder's blog recently: http://blogs.windows.com/windows/b/appbuilder/archive/2014/03/20/instrumenting-your-app-for-telemetry-and-analytics.aspx.

Thanks to everyone that downloaded my 15+Puzzle app and played with it a bit. I also had a number of folks in the audience do it during the talk, which made a compelling presentation. And yes, I did give away all the prizes I had…about 6 people approached me afterwards showing the app with a medal. :)

 


This page is the collection point for errata in my book, Programming Windows Store Apps with HTML, CSS, and JavaScript, Second Edition. If you find an error, please check the know error list below. If you've found a new error, please leave a comment with the details and I'll migrate into the body of this post. Thank you!

Multiple Chapters:

  • The website http://dev.windows.com has been revamped to include Windows Phone, Desktop, Hardware, and IE, so a "Dashboard" link no longer appears at this URI. To get to the right page, use the drop down along the top of the page to select "Windows Store Apps". This takes you to http://msdn.microsoft.com/en-US/windows/apps/ where "Dashboard" is visible.

To follow up on my previous post, one part of my demo at //build is the telemetry data gathered from my 15+Puzzle game in the Windows Store. You can find it here: http://apps.microsoft.com/windows/app/15-puzzle/2406fbef-c596-4ddf-88a6-34542562dd75.

It's free, so go install it, play some games between now and next Thursday at 5:30pm, and I'll have some extra data to show. Thanks!

1_first screen


Another post of mine on the App Builder's blog: http://blogs.windows.com/windows/b/appbuilder/archive/2014/03/19/instrumenting-your-app-for-telemetry-and-analytics.aspx

This is much of what I'll be covering in my talk at //build 2014 in two weeks, and the material also appears in Chapter 20 of Programming Windows Store Apps with HTML, CSS, and JavaScript, which is getting finalized now. (Watch http://aka.ms/BrockschmidtBook2 for that announcement.)



For some time I’ve been looking for a reliable equivalent to #ifdef DEBUG in a JavaScript app, as there are a number of needs to set up different code structures between the two build targets. This includes switching between Windows.ApplicationModel.Store.CurrentApp and CurrentAppSimulator, using test data vs. live data, using test URIs vs production URIs, using test accounts vs. live accounts, using different tokens for back end services, and so on..

I've seen some solutions that utilize t deterministic for JavaScript, but this isn't deterministic for JavaScript because you can debug a Release build just like a Debug build–all the source code is just there, so it's not like C++ where you lose your symbols. I've also seen hacky methods that check for "Debug" in the package install folder path, but that doesn't work for side-loaded apps (like you might share with testers) and maybe not for remote debugging.

It’s really best to get the target configuration straight from VS and somehow apply it to a project, and I worked out how to do it without a VS extension. See this small DebugRelease sample for a demonstration: http://kraigbrockschmidt.com/blog/?attachment_id=1287

What I did is create two .js files in the project (debug.js and release.js in a js-buildinfo folder) that I exclude from the end package by setting their Package Action to None instead of Content. I then use in MSBuild task to selectively copy one or the other file to a common name in the package (e.g. buildinfo.js).

Here are basic file contents:

debug.js:

(function () {
    "use strict";

    WinJS.Namespace.define("BuildInfo", {
        isDebugBuild: true,
        isReleaseBuild: false,

        config: "Debug",
        currentApp: Windows.ApplicationModel.Store.CurrentAppSimulator

        /*
         * Include debug-only data, service URIs, access tokens, accounts, etc.
         */
    });
})();

release.js:

(function () {
    "use strict";

    WinJS.Namespace.define("BuildInfo", {
        isDebugBuild: false,
        isReleaseBuild: true,

        config: "Release",
        currentApp: Windows.ApplicationModel.Store.CurrentApp

        /*
         * Include release-only data, service URIs, access tokens, accounts, etc.        
         */
    });
})();

To do the selective copy, it’s necessary to add a BeforeBuild action in the project file. At present, VS doesn’t allow custom build configuration for JS projects through the UI, so you have to do the following:

  • Right click and Unload Project in VS.
  • Right click and Edit the project manually.
  • Make the changes below.
  • Right click and Reload Project.

Editing the .jsproj file I added the following entries under the ItemGroup with the project files:

  <ItemGroup>
    <BuildFlagSource Include="js-buildinfo \$(Configuration).js" />
  </ItemGroup>
  <ItemGroup>
    <BuildFlagDestination Include="js\buildinfo.js" />
  </ItemGroup>

And then farther down there’s a section that’s commented—you uncomment it and add the <Copy> element shown here:

  <Target Name="BeforeBuild">
   <Copy SourceFiles="@(BuildFlagSource)" DestinationFiles="@(BuildFlagDestination)" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="true" />
  </Target>
  <Target Name="AfterBuild">
  </Target>
  <PropertyGroup>
    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
  </PropertyGroup>

Ideally you’d make buildinfo.js read-only in the project to prevent editing what will be overwritten in the build.

And the you can just have this line in whatever HTML files need it (usually before other .js files that would use the BuildInfo properties):

<script src="/js/buildinfo.js"></script>

Things I like about this solution:

  • It’s extensible as you can add anything you want to the debug.js and release.js files.
  • The BuildInfo namespace can include methods to do build-specific work, which is sometimes necessary.
  • It enabled isolation of all build-specific code in these files, rather than littering it throughout the rest of the app as you would with just a simple flag. I still have a flag in here as an option, but you wouldn’t have to use that at all.
  • It works no matter how an app is deployed.
  • It’s not dependent on any compiled VS extension that you’d have to produce for x86, x64, and ARM.

A few downsides:

  • Have to hand-edit a project and do some one-time configuration like adding a buildinfo.js and making it read-only.
  • You have to make sure that the debug.js and release.js files define the same stuff.
  • It feels a bit fragile given the manual steps.

What do you think of this solution? It works well and reliably applies the chosen build target to your JS code. But are there things I've missed or things that can be improved?


I've been buried with making several visits to Microsoft in Redmond, planning sessions for //build 2014, managing content for the Windows App Builder's blog, and wrapping up the second edition of my book (not to mention navigating Microsoft's top to bottom reorg!). Hasn't left much time for personal blogging, but I'll resume as soon as I can. Thanks for waiting!


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.