Category Archives: programming windows store apps

Css selector and its style rules are not picked up

Published July 23, 2013 11:38 am

When building a WinJS based windows store, many a times I run into the issue – css rule is not getting picked. then, begins the debugging to figure out what is going wrong. Sometimes, it has been quick and get to the solution; sometimes end up pulling hairs and decide to take it up some other day; sometime eliminate the problem by removing it thinking about ROI; sometimes strike a reasonable workaround.

Here is the listing of things that have come handy some time or the other:

  1. Seriously checking that css file is included in the html file; The path of the css file is indeed correct and does not have any typo. For example: today, I hit a case where I missed one directory in the folder path of the css file in a big size project.
  2. class names or the id name in the css selector does not match with what is mentioned in the html file. Following a naming convention reduces the probability of this cause over a period of time. For example – I happen to use some of these rules a) use camel casing for id b) use ‘-‘ as word separators in class names c) try to keep class names to 2-3 words d) pick class names that are intuitively represent the element
  3. Use VS->Debug->windows-> DOM Explorer -> select element and look through the styles and trace style for the desired element.
  4. Keeping the common css rules across projects into default.css.
  5. Prefixing the css selector long enough that it does not conflict with rules in other pages. For example – I happen to use a convention to give a unique class name for each page in the fragment element and use '.mypage.fragment' prefix in the css rules for the page.
  6. Layout rules have been most challenging at least in the beginning when using display: -ms-grid or display: -ms-flexbox . Over a period of time, there is understanding of how it works. Debugging issues here require a separate post though.
  7. Using WinJS builtin styles whenever possible since they are well tested and work for multiple layouts of the page. For example: .win-type-ellipsis to auto-ellipse the text if it is too long for the space. win-ring win-medium for a medium size progress ring. msdn pages for each control and skimming though the ui-light.css gives access to such classes.
  8. There can be many more items. but need to get back to work. Today I found this nice article that explains how a multiple rules fight over a given css selector in the section “cascading order”.

More later.

Adding asserts to WinJS application

Published July 8, 2013 2:49 pm

I have been coding without asserts Windows store application in javascript (WinJS based). Amidst making progress on frameworks for the next application, looking into this was at the back burner. One day, it pinched enough to look around for the solution.

I had been using chai.js for the assertions in the nodejs server code. It is expected to work in browser. hence, gave it a try to use it in WinJS application. It works; the library has right set of apis for the assertions in javascript.

What needs to be done:

  1. download chai.js for browser from here.
  2. Add the file to the vs project
  3. Add script entry into default.html
  4. Add a global variable – assert – in default.js
  5. Use the assert apis in code.

default.html:

<!-- WinJS references -->     
<link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />     
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>     
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>

<!-- external js libs -->     
<script src="/js/chai.js"></script>

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

default.js:

 
(function()
{
    ...
    assert = chai.assert;
})();
var assert;

Examples:

 
    assert.isObject(this.options);

    assert.isString(this.options.parameter1);

    assert.deepEqual({ tea: 'tea' }, { tea: 'tea' });
    //  for more examples - refer http://chaijs.com/api/assert/

Azure Table Rest API errors with WinJS application

Published June 7, 2013 11:10 am

If you are using azure SDK to code to its REST API – there are lot of API nuance that is taken care by the SDK. For example – if you are coding nodejs server, or windows store application using c# that uses Azure, nodejs and .net sdk is available. For WinJS, there isn’t azure sdk.

But it shouldn’t be big deal to code directly to the REST API if the basic http lib is available. `WinJS.xhr()` is available to mimics closely what XmlHttpRequest does in the browser. Well, this holds true if the API returns meaningful errors with sufficient contextual details for the error. If that isn’t true, lot of developer(your) time is wasted debugging the error cases. Keep binging to see if other community developer hit similar issue, or parse the http packets sent — for a successful rest api call made by other tool or application – using fiddler or network monitor.

I recently saw two such errors when invoking azure table rest api to query using javascript in WinJS application.

  1. AuthenticationFailed
    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
      <code>AuthenticationFailed</code>
      <message xml:lang="en-US">Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.</message>
    </error>
  2. InvalidHeaderValue
     
    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
      <code>InvalidHeaderValue</code>
      <message xml:lang="en-US">The value for one of the HTTP headers is not in the correct format.</message>
    </error>

AuthenticationFailed was hit when the x-ms-date header was formatted incorrectly. Expected value – Thu, 06 Jun 2013 08:09:50 GMT . Value computed in the code – Thu, 6 Jun 2013 08:20:34 GMT. Note: the difference in ‘0’ prefix for the date. Because of this, the computed stringToSign for the authorization header was incorrect. For details, you can refer here.

InvalidHeaderValue was hit because MaxDataServiceVersion: '2.0;NetFx' header value was missing.

In the first case, if the REST API returned the expected and found ‘stringToSign’ parameter value in the returned error – it would help developer save order of .5 to 1day worth of debugging time. In the second case, if the returned error mentioned the missing header in the error details, again it will save 1-2 hours of debugging time.

Well, you might hit here and cause & solution of the error code for the same api might be different than this – do drop a comment with the cause & solution. If you are a developer coding REST API, do send error codes with sufficient details to save hours of developer time. Thanks for reading so far.

Handling click event on elements within WinJS Listview ItemTemplate

Published May 29, 2013 5:26 pm

Typically – there is need to handle ‘itemInvoked’ event in a ListView. but there are some cases when you are looking for handling click event on a element defined in list view item template. Since item template is rendered multiple times for each item in the list view, how do we do this?

Let’s take an example where item template has two anchors. On click on each anchor, you want to tranverse to another page but parameter passed to the page will differ based on which anchor was clicked.

<div id="itemTemplate" data-win-control="WinJS.Binding.Template">
    <div>
        <h3 class="win-type-ellipsis date cell" data-win-bind="innerText: date"></h3>
        <h3 class="win-type-ellipsis hour cell" data-win-bind="innerText: hour"></h3>
        <a class="win-type-ellipsis counter1 cell" data-win-bind="innerText: counter1" ></a>
        <a class="win-type-ellipsis counter2 cell" data-win-bind="innerText: counter2" ></a>
    </div>
</div>

To do this, we need to register a wrapper itemTemplate function in code like this. That will enable us to register event handlers for counter1 and counter2 cells.

    listView.winControl.itemTemplate = this._itemTemplate.bind(this);
    _itemTemplate: function itemTemplate(itemPromise)
    {
        var self = this;
        var container = document.createElement('div');
        return itemPromise.then(function onitem(item)
        {
            return itemTemplate.winControl.render(item.data, container);
        }).then(function onrendercompete(c)
        {
            // register event listener
            var counter1Element = c.querySelector('.counter1);
            var counter2Element = c.querySelector('.counter2);
            counter1Element.onclick = self._oncounter1click.bind(self);
            counter2Element.onclick = self._oncounter2click.bind(self);
            return container;
        });
    },

In the event handler, we can use ListView.indexOfElement() method to get the item corresponding to the element clicked.

    _oncounter1click: function oncounter1click(event)
    {
        this._navigateToRequestsPage(event.currentTarget, 'counter1');
    },
    _oncounter2click: function oncounter2click(event)
    {
        this._navigateToRequestsPage(event.currentTarget, 'counter2');
    },
    _navigateToRequestsPage: function navigateToRequestsPage(itemElement, counterFlag)
    {
        var index = hourlyStatListView.winControl.indexOfElement(itemElement);
        var item = this.viewModel.items.getAt(index);
        var hour = item.date + 'T' + item.hour;
        WinJS.Navigation.navigate('/pages/itemDetails/itemDetails.html', { hour: hour, counterFlag: counterFlag});
    }

In summary, we saw how we can use wrapper item template function to register event handlers with elements declared within item template. We also saw the use and relevance of ListView.indexOfElement() function in the scenario.

Integrating your windows store app with https nodejs web service

Published May 16, 2013 12:56 pm

During development, we typically start implementing the web service as a http endpoint. At a later stage in development we need to make it a https endpoint. This is when we need to deal with SSL certificates.

Hosting the nodejs web api server at custom https endpoint like https://myapi.mywebsite.com, buying the SSL certificate for the api subdomain from a certificate authority, getting the required .pfx file from the files given by CA for the https nodejs server are interesting topics by themselves. Today, we are talking about generated a self-signed certificate for the localhost. This enables us to run the https nodejs web server on local machine and test the windows store application to consume the apis. This suffices for the development of the app & service while other things are required for taking the app to production.

I found this helpful tool through bing to generate self signed certificate for locahost, has the nice GUI and gives a pfx file as output. Saves going through the VS command line makecert details unless you already know about it.

https nodejs server is up and running given the localhost pfx file and its password.

var fs = require('fs'),
    https = require('https');

var options = {
    pfx: 'localhost.pfx',
    passphrase: 'your password',
};

https.createServer(options, function (req, res)
{
   ...
}).listen(xyz);

but when my WinJS client WinJS.xhr() calls fails to https://localhost:xyz/
This is because the certificate authority is not trusted by the localmachine – the dev box. The localhost certificate needs to be added to ‘trusted root cas’ using certificate mgr mmc. To do this:

  1. Launch mmc. Add ‘certificates’  MMC snapin. select local computer.
  2. Right click ‘Trust Root Certificate Authorities’-. Follow All Tasks->Import to import the localhost.pfx certificate here.
  3. Follow the instructions in the import wizard

Once done, WinJS client can successfully connect to the https://localhost:xyz nodejs endpoint.

Getting oauth authentication code for windows live account in windows store application

Published May 13, 2013 1:26 pm


We need to add support to login using windows live into the windows store application. The backend web service authenticates the user identity using one of the well known providers – google, facebook and now windows live.

WebAuthenticationBroker comes handy to get authentication code in the windows store app. authentication code is passed to the backend web service. sample code below:

Windows.Security.Authentication.Web.WebAuthenticationBroker.authenticateAsync(
    Windows.Security.Authentication.Web.WebAuthenticationOptions.none,
    // redirect_uri parameter is encodeUriCcomponent('https://login.live.com/oauth20_desktop.srf')
    //  scope can be wl.basic others. refer other scope values here
    // client id is created by adding your application here
    new Windows.Foundation.Uri('https://login.live.com/oauth20_authorize.srf?client_id=&redirect_uri=https%3A%2F%2Flogin.live.com%2Foauth20_desktop.srf&response_type=code&scope=wl.emails'),
    new Windows.Foundation.Uri('https://login.live.com/oauth20_desktop.srf')).then(
       function (result)
       {
           if (result.responseStatus === Windows.Security.Authentication.Web.WebAuthenticationStatus.success)
           {
               var uri = new Windows.Foundation.Uri(result.responseData);
               var code = uri.queryParsed.getFirstValueByName('code');
           }
       }).then(null, function onerror(innerError)
       {
           // handle error
       });

Important notes:

  1. http://login.live.com/oauth20_token.srf api to get token from authentication code fails with 500 internal server error if HTTP POST is used as per documentation. HTTP GET has to be used instead. documentation is out of date. Refer this thread at msdn.

Sign in using Twitter in your app and protecting your twitter consumer secret

Published May 10, 2013 12:53 pm

Recently I am working on authentication and authorization for our backend service. The service will be integrated with some of our store apps. Obvious thing is to enable signup/signin for user using providers like facebook, google, twitter etc. I used oauth 2.0 apis to authenticate with facebook, google and added authorization functionality (to give access token for our apis) in the service.

As part of this effort, was looking at adding twitter support. Twitter oauth api requires consumer key and secret for any request. That means shipping your consumer secret with your app. quick search on net revealed that there were many other folks facing the same issue. thread 1, thread 2, etc.

Summary based on my few hours looking into this is:
1. Twitter does not support oauth 2.0 which support concept of intermediate auth code. When using this flow, way mobile client does not need to put consumer secret key in the client (app) code. Without this, consumer secret needs to be put in the client code. It can be obfuscated but risks associated with leaking your consumer secret, will not be completely mitigated.
2. I do wonder why twitter does not support oauth 2.0 yet?
3. There is likely way out if the whole authentication UI flow is moved to your app server side. client uses webview/browser to walk user through the authentication and authorization flow, starting with a page on your web site; eventually get the access token to the service. related thread

Currently – we will not support twitter sign in, and not try to move the whole signup/signin UI to server side. When the app is ported to say android, will revisit this.

Did you solve similar problem where you had a mobile app with your backend service, wanted to authenticate using well known providers but manage access token for your service apis yourself? Did you keep the signup/signin UI on your web server? Did you use azure ACS service all together to solve it for you?

Creating a Bindable object in javascript for Windows store application

Published April 8, 2013 6:57 pm

When I was writing windows store application in c#, it provided

class BindableBase

I was looking for similar way to create bindable object in javascript using WinJS library. WinJS libray does have WinJS.Binding.as() method that can be used to make an object observable through a proxy. but I was looking for a way to make the object itself Observable.

var MyViewModel = WinJS.Class.define(
    function MyViewModel_ctor()
    {
        this._initObservable();
        this.bind('property1', this._onproperty1change.bind(this));
    },
    {
        _onproperty1change: function onproperty1change(newValue)
        {
            // can be used to update properties that are dependent on property1
            // property3 and property4 for example - can be updated here. UI will be 
            // notified if it is binding to these properties
        },
    });

    WinJS.Class.mix(MyViewModel,
        WinJS.Binding.mixin,
        WinJS.Binding.expandProperties({ property1: '', property2: ''}));

With little help from the quickstart and reading the WinJS base.js class helped arrive to this code and understand how it works.

var expandProperties = function (shape) {
    var props = {};
    function addToProps(k) {
        props[k] = {
            get: function () { return this.getProperty(k); },
            set: function (value) { this.setProperty(k, value); },
            enumerable: true,
            configurable: true // enables delete
        };
    }
    while (shape && shape !== Object.prototype) {
        Object.keys(shape).forEach(addToProps);
        shape = Object.getPrototypeOf(shape);
    }
    return props;
};
  1. WinJS.Binding.expandProperties documentation won’t help to understand what it brings. The snippet from the base.js above clarifies that it adds properties for each key specified in the parameter, and the value specified is not used for anything.
  2. WinJS.Binding.mixin object brings the getProperty/setProperty/bind/notify and bunch of other methods for the object
  3. _initObservable() need to be invoked from the constructor to initialize _backingData field. The _backingData object is used to store the property values.
  4. this.bind helps you get notified for a property change, and it can help in scenario like updating dependent properties.
  5. It saves writing boiler plate code for each property in the view model object

Did you need something like this? Have you solved in different way than this?

Adify your windows store application

Published April 3, 2013 10:17 pm


I have added Microsoft advertising into one of our windows store app couple of months back, and have been following the pubcenter reporting to see how ads work. Lets talk a little bit on adifying your windows store application and few observations on what they fetch to app developer.

It is quite a simple process and well documented in msdn. Nevertheless, few observations – we make here – might be relevant for you and HTH. Details here will be for a javascript based windows store application.

  1. Download the Microsoft advertising sdk here
  2. In your visual studio project -> add reference  -> add the javascript library advertising.
  3. Follow this walk through to add the ad html snippet into your app.

Html snippet looks something like this.

<div id="myAd" style="position: absolute; top: 53px; left: 0px; width: 250px; height: 250px; z-index: 1;" 
   data-win-options="{applicationId: 'd25517cb-12d4-4699-8bdc-52040c712cab', adUnitId: '10043105'}" 
   data-win-control="MicrosoftNSJS.Advertising.AdControl">
</div>

To test the app with ad, test application id and test ad units needs to be used. The guid mentioned above is test application id. Test ad unit id will depend on the size of the ad unit. refer here.

Few things to keep in mind when testing the application with ad unit(s)

    1. width and height mentioned in the css do not match the size of the ad unit. ad won’t be served in this case.
    2. some times ads does not load because there are not ad available for the application. good to register for the error handler as mentioned here and put a break point in the method, to get the event with error message.
    3. Test your application with test ad units only, not real ad units. For real ad units, you have register your live account with Microsoft advertising and create ad units for your windows 8 application.
    4. I typically follow the practice of switching to test ad units for development. Microsoft advertising otherwise might think the app owner itself fetching ads for its application and/or clicking its own ads.
    5. To start with, you may want to just place the ad in the default.html as bottom/side or top bar. Eventually, you may want to customize, place right size ad units at right place in your app pages.
    6. Ad must catch the sight of the user at the end of the day and use appropriate empty slot on the page.
    7. Using too many ad units on a page, may spoil the app branding. Typically using one ad unit in a page might be good idea.
    8. Ad unit size and type will need to gel well with the page content so that page look-and-feel professional with ad. For example – sometime placing an ad unit 250x250px within the page, looks more suitable for a page than placing 729x90px bottom image bar
    9. Need to consider & test multiple page views – snapped, portrait, filled and landscape – for the ad unit(s) in the page. css styling with @media query can be used for the layout.
    10. We have used ad-area-host outer div to host the ad unit div. That gives flexibility to position the ad unit since the ad unit always have to size as specified during creation. snippet below allows to center the bottom ad bar.
 
<div class="ad-bottom-area-host">
    <div class="ad-area"
        data-win-control="MicrosoftNSJS.Advertising.AdControl" 
        data-win-options="{applicationId: d25517cb-12d4-4699-8bdc-52040c712cab', adUnitId: '10042998', onErrorOccurred: errorLogger }">
    </div>
</div>

/* below code is from the corresponding css file */
.ad-bottom-area-host
{
    -ms-grid-row: 3;
    -ms-grid-column-span: 2;
    height: 90px;
    display: -ms-flexbox;
    -ms-flex-direction: column;
    -ms-flex-align: center;
}

.ad-bottom-area-host .ad-area
{
    width: 728px;
    height: 90px;
}

ad-bottom-area-host is placed inside another grid and spans two column cells. it uses flexlayout to center the ad-area at the bottom of the page. ad-area is sized as per the requirements of the ad unit.

What ads fetch to the app developer:

  1. Everyone would think that ads fetch monetary returns to app developer. but typically it takes time if the app gets high usage.
  2. we have seen eCPM grow over time.
  3. The best thing that advertising fetches is the hourly reporting of impressions. given the impressions and fill rate – it gives rough indication of the usage of the app broken down to hour. given the app usage reporting in windows store analytics was broken, and continues to be broken – this data is useful.
  4. if you are new to advertising or app development, gives you the first hand feel of advertising & its jargon which you will not get by reading blogs or articles.

Are there other advertising networks that can be used for windows 8 store app? I did look briefly into it. but can talk about it in a separate post.

References

  1. Microsoft advertising sdk for window 8 – documentation

 

Uploading image to azure blob from windows store app

Published March 22, 2013 11:11 am


msdn gives quick start to upload image file using background transfer.  but I was looking for way to upload image file using WinJS.xhr() in the javascript app.

Windows.Storage.Pickers.FileOpenPicker.pickSingleFileAsync() returns StorageFille object  whereas WinJS.xhr.send() expects a File DOM object. Essentially, what we need is way to get a w3c File DOM object out of StorageFile object. I found finally the method MsApp.createFileFromStorageFile() to do that.

// url needs to be SAS (shared access signature) url for the blob when the container is protected
// otherwise - it requires putting authorization code in the request. I have talked about in previous post.
// but if the javascript is in the client side - you wont like to put your client secret in the app.
// hence, you need to have some mechanism (your service) to return the sas url for your azure container/blob. 

    var url = '';
    var date = new Date().toGMTString().replace('UTC', 'GMT');
    var data = MSApp.createFileFromStorageFile(storageFile);
    var xhrOptions = {
        type: 'PUT',
        url: blobSasUrl,
        headers: {
            'Content-Type': 'image/jpeg',
            'Content-Length': data.size,
            'x-ms-date': date,
            'x-ms-version': '2009-09-19',
            'x-ms-blob-type': 'BlockBlob',
        },
        data: data,
    };
    WinJS.xhr(options).then(null, function onerror(error)
    {
        // handle error
    });

I see that many of us need to upload images to azure blob containers. If you are one of us, it will help to know little bit more to help you better.