Developing for Windows Phone 8 in Apache Cordova

Win_Cordova

by Jesse MacFadyen

There’s a new device in town. It is getting some attention as the design maverick, and it’s owners are a passionate bunch. Microsoft has stepped up their commitment to the Windows Phone platform with Windows Phone 8. Having received numerous accolades for defining their own path, instead of following the crowd, Windows Phone 8 takes a leap forward from the firm footing defined by Windows Phone 7.  This article will help you get started developing for Windows Phone 8 using PhoneGap.  If you are porting an app from another PhoneGap supported device, you are well on your way and should not have much work to make it all run in Windows Phone 8.

A Crash Course in Windows Phone 8

Wait!? What about Windows Phone 7?

The first question you may ask yourself is whether you want to support WP7. There are still WP7 devices out there, so you have to consider the users that do not upgrade right away. If you choose to build your PhoneGap app for WP7, the application will still run on WP8 devices, however, all the WP7 quirks will still be there, and you will be missing out on some of the new shiny features of WP8.

Microsoft has thought of this, and does allows you to have a single product listing in the store, but upload 2 XAP (Application Package) files, one for each device. When users visit the store and install the app, they will be given the correct version for the device they are using. This allows you to take advantage of the new features, without appearing to leave anyone behind, but it does mean that you may still need to manage 2 versions of your app.

PhoneGap for WP7 and WP8 are currently maintained as different repositories, although there is some redundancy that the team hopes to resolve by merging in the near future.

What is new in WP8?

The most important change, from a PhoneGap perspective, is that WP8 has a better browser. In Windows Phone 7.1, the web browser control used IE9. Unfortunately IE9 did not support any type of touch events when used as a control. The DOM would receive a mouse-down event, and then when the user moved their finger, the DOM would not receive any more events, as they were captured by the control. I spent considerable effort to find a suitable workaround for this, and was eventually able to support mousedown, mousemove, and mouseup.

In WP8, the browser control has been upgraded to IE10, and the workaround is no longer needed. IE10 supports a new multi-touch model called PointerEvents which has been submitted to the W3C for consideration as a standard.

While not exactly the same thing as WebKit’s touchevents that we have become used to on other devices, it is not hard to support both, so we at least have the same abilities across devices.

Another annoyance that is fixed moving to WP8 is the large grey box that IE9 would draw on any clicked DOM element, Microsoft has listened to developers who want to style their buttons themselves, and now allows you to do so.

Microsoft has supported PhoneGap since WP7 (the Mango update aka 7.5) so they are very aware that many developers are coming from WebKit-based browsers, and many website developers may have issues moving their mobile sites to support IE10.  To address this, they have written an extremely useful guide to help cover the important differences.

IE10 is Microsoft’s most standards compliant browser to date, and shows their commitment to making the web better, and helping define the future standard.

Are You Responsive?

WP8 introduces different resolutions, and because PhoneGap apps are rendered in a browser component that fills the screen, this makes responsive design more important than ever.  WP8 devices are available in WVGA(480×800), WXGA(768×1280), and 720p(720×1280)

Permissions
PermissionsPermission models vary from platform to platform, and Windows Phone has had it’s own quirks to deal with. There is the concept of an app-manifest, in which you define the capabilities that your application needs. These capabilities are then displayed to the user in the store before they download your app so they can make an informed decision of whether to trust your app, knowing it can only access the capabilities specified.

This fell apart on Windows Phone 7 because when you submit your app to the store, it is run through a ‘static analyzer’ that determines what capabilities are required by the app, regardless of what was specified in the manifest. PhoneGap apps for Windows Phone 7 link to a dll that provides the full PhoneGap API functionality, so any app using the dll will appear to require access to every API, even if it doesn’t. Interestingly, the manifest does prevent calls to APIs that are not specified as capabilities, and an error result is returned, but having these capabilities all listed may prevent some users from downloading your app.

Windows Phone 8 has addressed this, so that the only capabilities shown to the user are the ones specified in your manifest.

New Sensors and New Plugin Opportunities

WP8 introduces some new APIs including NFC, and a SpeechAPI.  Hopefully a reader of this article will be inspired by how easily this all works, and go and write a PhoneGap plugin for this new functionality. WP8 also supports PushNotifications, and In-App purchases, which represent a big opportunity for cross-device plugins.

Trial Mode

The Windows Phone store has always had a strong tool for getting people interested in your app. Trial offers allow users to download your app for free, and evaluate it. Trials can be for a limited time, or you can limit features based on whether or not the user has paid, or some combination of the two.

Beta Testing

The Windows Phone store also allows you to manage your own beta test groups. You can add up to 10,000 email addresses to beta test an app. Beta testers can see the app in the app store, just as if it was available to everyone. This lets you not only test the performance of your app on multiple devices, but gives you a chance to fine tune your meta data, and marketing by seeing the exact store experience before going live.

Updates are unfortunately a little slow through the beta process as the new binary has to be run through a process similar to the app store submission process, and the system must do some processing before your update is live. Generally it is a couple hours though.

The beta-testing functionality is available to both WP7 and WP8, or a single product that targets both with separate XAP files.  Essentially it is identical to the store submission process.

Hello PhoneGap Windows Phone 8

After you have gone through the requirements setup we can start a new project in Visual Studio. Choose to build a new CordovaWP8_2_5_0Full app.

The Project Layout

Project LayoutJust like other PhoneGap supported platforms, we will only be concerned with the files in the www folder.  This is essentially our web-root and index.html is our default opening page.

The template gives you a good starting point for developing an app.  The index.html includes an external js file ( index.js ) to contain the app logic, and places relevant styles in a the index.css file.

Looking at index.js, we see the app simply waits for Apache Cordova to fire the ‘deviceready’ event, and then it updates the view.

Run this on your attached device, and or the emulator, and you should see the view update immediately after loading.

Compass Example

Let’s look at how to connect to an API via PhoneGap on Windows Phone 8.  In the example, we’ll examine using the Compass API as is not typically available to web pages, and requires native access.

Creating the Project

Again we will start with the project template, but this time we will be making some changes.

Compass ProjectFrom the project in the ‘Solution Explorer’ window, you can add or remove files. All files that you want to access at runtime, including scripts, style-sheets, and images, must be part of the project, and must be flagged as ‘content’  so that Visual Studio knows to package the files with your app.

For this example we are going to add an image, and put all css and js in the index.html file, so everything is viewable at once.  This approach is fine for small projects, but quickly becomes difficult to maintain once it is more than just a very simple demo.

The 2 files needed are in the zip [CompassDemo.zip].

To get started :

  • Delete the css, js, and img folders from your project
  • Drop in the updated index.html
  • Add the CompassRose.png image
  • Build and Run the app ( this example needs to be run on a device, because the emulator does not have a compass sensor. )

A Closer Look

Looking at the script in index.html, we see the familiar ‘wait for deviceready’ pattern.

The start/stop button is hooked to a simple function that wlll make our PhoneGap API call to start/stop the compass.

function toggleWatch() {
    errMsg.innerText = "";
    if (compassWatchId) {
        navigator.compass.clearWatch(compassWatchId);
        compassWatchId = null;
        toggleBtn.innerText = "Start Watch";
    }
    else {
       compassWatchId=navigator.compass.watchHeading(onHeadingUpdate, 
					    onCompassFail, 
					   {frequency:1000});
       toggleBtn.innerText = "Stop Watch";
    }
}

Calling navigator.compass.watchHeading starts the compass watch, and returns a watchId.  We store the watchId so that later we can use it to stop the compass.  We set this id to null after we stop the compass so that we can  use it to tell if the compass is already running, and update the button text accordingly.

navigator.compass.watchHeading takes 3 parameters. The first is a success callback function which will be called repeatedly when new data is retrieved from the compass sensor.

The second parameter is an error handling function that will be called if there is an error.  Errors could include permission issues, or that there is no compass on the device.

The third parameter is an object literal, that allows you to define some options.  For example, the compass.watchHeading API allows us to specify a frequency for how often we would like to be updated.  In this case we are specifying that we would like to be updated every 1000 milliseconds, or once per second.

onCompassError simply looks at the error code that is passed to it, and outputs some text to let you know what has happened.

function onCompassFail(err) {
    var msg = err == CompassError.COMPASS_NOT_SUPPORTED ? 
                     "Compass not supported" : 
                     "Internal Error";
    errMsg.innerText = "Compass Error : " + msg;
}

The success handler, onHeadingUpdate is passed a CompassHeading object.  We update the rotation of the compassRose image based on the ‘trueHeading’ property,  which is the number of degrees returned by the compass.  It is important to note that compass degrees are in the opposite direction to css rotation degrees, so we rotate our image using rotate(-” + heading.trueHeading + “deg) ; That’s a very important minus sign there.

All the remaining information available is output as text in the document as well.

function onHeadingUpdate(heading) {
    compassRose.style.transform = "rotate(-" + heading.trueHeading + "deg)";
    trueHeadingTxt.innerText = "trueHeading : " + heading.trueHeading;
    magHeadingTxt.innerText = "magneticHeading : " + heading.magneticHeading;
    accuracyTxt.innerText = "headingAccuracy : " + heading.headingAccuracy;
    timestampTxt.innerText = "timestamp : " + heading.timestamp;
}

Compass Sample App

Where to go from here

We’ve covered a lot of ground, and you should be well on your way to bringing all your PhoneGap apps to Windows Phone 8.

If you are interested in more device API focused samples, the documentation itself includes brief samples for every supported API.  I recommend you start there.

I welcome questions on twitter: @purplecabbage

3 Comments

  1. Pingback: Join the PhoneGap Windows Phone Porting Challenge | SDK News

  2. Giancarlo said:

    I tried it using phonegap 2.3.0 but when the app runs appear message of error. I wonder if you can upload the source code to download it

*

*

Top