Using PhoneGap in Windows 8 Store Applications

[Infragistics] Mihail Mateev / Sunday, January 6, 2013

In a series of blogs you will learn about how to use PhoneGap with the new cutting edge Microsoft platforms – Windows 8 and Windows Phone 8. We will talk how to start and how to use PhoneGap with popular web client frameworks like jQuery Mobile and Infragistics Ignite UI.

What is PhoneGap?

PhoneGap (previously called Apache Callback, now Apache Cordova) is an open-source mobile development framework produced by Nitobi, purchased by Adobe Systems. It enables developers to build applications for mobile devices using JavaScript, HTML5 and CSS3, instead of device specific languages such as C# or Objective-C. The resulting applications are hybrid, meaning that they are neither truly native (layout rendering is done via web views instead of the platform's native UI framework) nor purely web-based (because they are not just web apps, but are packaged as apps for distribution and have access to native device APIs).

There are many topics about PhoneGap in iOS and Anrdoid applications and only few related to Windows 8 and Windows Phone 8. Hope that it will be interesting for developers to know why and how to use this framework with Microsoft platforms.

 

PhoneGap for Windows 8 Store Applications.

Windows 8 apps can be designed and coded using HTML, CSS and JavaScript just like PhoneGap apps can. And with very little effort you can use your skill and existing resources to have a modern looking Windows 8 app in no time.

PhoneGap and Windows 8 development are more similar than you realize

What you can take as an advantage when you create PhoneGap applications for Windows 8

  • Your skills, assets, and probably a lot of your existing pure HTML/CSS and JavaScript code will just work in a Windows 8 application.
  • You can update the look of your applications with very little effort by using the intrinsic styles for the basic HTML elements like <h1> and <button>, as well as the advanced Windows 8 controls like the  app bar, date picker, flip view, and more.
  • Your code that interacts with the PhoneGap API (to handle things like file access, sensors and application lifecycle events) can be updated to use the WinJS library to accomplish the same things you were doing in PhoneGap.
  • Scenarios where you had to write PhoneGap plugins can be addressed by either finding the functionality in the expansive WinJS library, or by incorporating native code in a Windows 8 JavaScript app.

In this article we will talk about different ways to create Windows 8 Store applications with PhoneGap and will make a simple comparison between Windows 8 Applications with PhoneGap and those that use only WinJS

 

How to Create PhoneGap applications for Windows 8

There are three different ways to start with Windows 8 and PhoneGap

  • To create a new Windows 8 JavaScript project and add PhoneGap references manually
  • To start with PhoneGap startup project included in the distribution
  • To build a PhoneGap Windows 8 template and use it in Visual Studio 2012

 

Create a new Windows 8 JavaScript project and add PhoneGap references manually

What you need to start:

  • Windows 8
  • Visual Studio 2012 Professional or better, or Visual Studio 2012 Express for Windows 8

 

Create a PhoneGap Windows 8 application

  • Download latest PhoneGap 2.x - https://phonegap.com/download or PhoneGap project from the Github : https://github.com/phonegap/phonegap/tree/master/lib/windows8 
  • Create Blank JavaScript project.
  • Add “cordova-2.x.js” JavaScript file to your js folder. (Located in \lib\windows8)
  • Change default.html to index.html(optional).
    Microsoft continues to use default.html as the default page for use in websites, whereas most "open web" developers use index.html. (Plus it's likely that in the other platform variants of your project you are using index.html as the name of your default page.) To fix this, in Solution Explorer rename the default.html file to index.html. Then double-click the package.appxmanifest file and change the Start page value to index.html.
  • Add reference to cordova-2.x.js file from default.html/index.html page
  • Adding a ’deviceready’  handler... (optional)

You can read more details here.

 

You could start your Windows 8 PhoneGap application from JavaScript Windows Store Blank App template

 

If you want to change default.html to index.html you need also change the name of the start page in the package.appxmanifest file.

 

It is a good practice to add a ‘deviceready’ handler to be possible let your application to know when PhoGap libraries are fully loaded.

The Cordova deviceready event fires once Cordova has fully loaded. After the device has fired, you can safely make calls to Cordova function.

 

Start with PhoneGap startup project included in the distribution

The official PhoneGap distribution and most of Apache Cordova source branches in the GtiHub have for each supported platform a template folder where is located a startup project. For some reasons most of distributions don’t include a ready for use Visual Studio project template but you could start your applications from a copy of this project.

 

Open the /lib/windows8/template folder from your distribution.

 

Check the settings in your package.appxmanifest  and you can continue with the development of applications with PhoneGap.

 

Create a PhoneGap Windows 8 template

It is more convenient if you have Visual Studio project template for Windows Store PhoneGap applications. As it was mentioned before for each supported platform there is a template folder where is located a startup project, but for Windows 8 there is not a ready for use project template. You could create a Visual Studio 2012 project template from this startup project. For Windows 8 it is located in /lib/windows8/template folder from your distribution.

Most of Cordova implementations provide CordovaBuilder project that could generate a Visual Studio 2012 project templates. Unfortunately CordovaBuilder project for Windows 8 is not updated from several months. It works correct for some implementations like this https://github.com/01org/cordova-win8  but raise exceptions in the newest versions of PhoneGap because of project structure changes. More details how to build a Visual Studio Windows Store project template with CordovaBuilder you could find here. If you are using the latest version you need to update a CordovaBuilder.cs file.

 

Another approach is to create your template manually.

Custom project templates require the following items

  • A metadata (.vstemplate) file that Visual Studio uses to define how to display the project in the IDE and, if you have specified the appropriate properties, to customize how the project is created in the IDE.

  • A project file.

  • Code files such as Web forms, class files, and resource files.

In Cordova distribution you need add only a metadata file named MyTemplate.vstemplate and add a correct template settings.

 

A sample metadata (.vstemplate) file.

   1: <VSTemplate Version="3.0.0" xmlns="https://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
   2:   <TemplateData>
   3:     <Name>Template-Cordova2</Name>
   4:     <Description>&lt;No description available&gt;</Description>
   5:     <ProjectType>JavaScript</ProjectType>
   6:     <ProjectSubType>
   7:     </ProjectSubType>
   8:     <SortOrder>1000</SortOrder>
   9:     <CreateNewFolder>true</CreateNewFolder>
  10:     <DefaultName>Template-Cordova2</DefaultName>
  11:     <ProvideDefaultName>true</ProvideDefaultName>
  12:     <LocationField>Enabled</LocationField>
  13:     <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
  14:     <Icon>__TemplateIcon.ico</Icon>
  15:   </TemplateData>
  16:   <TemplateContent>
  17:     <Project TargetFileName="CordovaApp.jsproj" File="CordovaApp.jsproj" ReplaceParameters="true">
  18:         <Folder Name="www" TargetFolderName="www">
  19:           <Folder Name="css" TargetFolderName="css">
  20:             <ProjectItem ReplaceParameters="true" TargetFileName="index.css">index.css</ProjectItem>
  21:           </Folder>
  22:           <Folder Name="img" TargetFolderName="img">
  23:             <ProjectItem ReplaceParameters="false" TargetFileName="logo.png">logo.png</ProjectItem>
  24:             <ProjectItem ReplaceParameters="false" TargetFileName="smalllogo.png">smalllogo.png</ProjectItem>
  25:             <ProjectItem ReplaceParameters="false" TargetFileName="splashscreen.png">splashscreen.png</ProjectItem>
  26:             <ProjectItem ReplaceParameters="false" TargetFileName="storelogo.png">storelogo.png</ProjectItem>
  27:           </Folder>
  28:           <Folder Name="js" TargetFolderName="js">            
  29:             <ProjectItem ReplaceParameters="true" TargetFileName="index.js">index.js</ProjectItem>
  30:           </Folder>
  31:           <ProjectItem ReplaceParameters="true" TargetFileName="cordova-2.3.0.js">cordova-2.3.0.js</ProjectItem>
  32:           <ProjectItem ReplaceParameters="true" TargetFileName="index.html">index.html</ProjectItem>
  33:         </Folder >
  34:       <ProjectItem ReplaceParameters="false" TargetFileName="package.appxmanifest">package.appxmanifest</ProjectItem>
  35:       <ProjectItem ReplaceParameters="false" TargetFileName="CordovaApp_TemporaryKey.pfx">CordovaApp_TemporaryKey.pfx</ProjectItem>
  36:     </Project>
  37:   </TemplateContent>
  38: </VSTemplate>

More details about Visual Studio project templates you could find here.

 

When you are ready just zip the all content of your /lib/windows8/template folder .

Copy your zip file in your  \My Documents\Visual Studio 2012\Templates\ProjectTemplates\Language\ folder. In this case language is JavaScript.

 

Then open a new instance of Visual Studio 2012 and select File->New->Project you will see your project template.

 

When you select Template-Cordova2 item from the list you will have a Windows 8 with PhoneGap startup project.

 

 

PhoneGap vs. WinJS 

 

The main difference between PhoneGap and WinJS is in the API. When you need to access some device resources you need to use different APIs . For example for geolocation in Cordova you need to use navigator.geolocation.getCurrentPosition(…) function. In WinJS library you need to create an instance of Geolocator: var geolocator = Windows.Devices.Geolocation.Geolocator(); and then to call  geolocator.getGeopositionAsync().

 

A showLocation  function using PhoneGap

   1: function showLocation() {
   2:      navigator.geolocation.getCurrentPosition(function (location) {
   3:          $("#locationResult").innerHTML = "Latitude: <strong>" + location.coords.latitude + "</strong><br/>Longitude: <strong>" + location.coords.longitude + "</strong>";
   4:      }, function (err) {
   5:          $("#locationResult").textContent = "Error getting location";
   6:      }, { timeout: 30000, enableHighAccuracy: true });
   7:  }

 

The same showLocation  function  using WinJS

   1: function showLocation() {
   2:  
   3:      var geolocator = Windows.Devices.Geolocation.Geolocator();
   4:      geolocator.desiredAccuracy = Windows.Devices.Geolocation.PositionAccuracy.high;
   5:      geolocator.getGeopositionAsync().then(getCurPosHandler, errHandler);
   6:  
   7:  
   8:  }

 

 

Windows Store JavaScript Applications with PhoneGap

 

index.html code

   1: <!DOCTYPE html>
   2: <html>
   3: <head>
   4:     <meta charset="utf-8" />
   5:     <title>PhoneGap Demo App</title>
   6:    
   7:  
   8:     <!-- WinJS references -->
   9:     <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
  10:     <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
   1:  
   2:     <script src="//Microsoft.WinJS.1.0/js/ui.js">
   1: </script>
   2:  
   3:      <!-- Cordova -->
   4:     <script src="/js/cordova-2.2.0.js">
   1: </script>
   2:  
   3:     <!-- PhoneGapDemoApp references -->
   4:     <link href="/css/default.css" rel="stylesheet" />
   5:     <script src="/js/default.js">
   1: </script>
   2: </head>
   3: <body>     
   4:     <p>Content goes here</p>
   5:     <h1>PhoneGap for Windows 8 - Demo</h1>
   6:      <script type="text/javascript">
   7:  
   8:          console.log("Subscribing top  deviceready event...");
   9:          document.addEventListener("deviceready", function () {
  10:  
  11:              navigator.notification.alert("This device is ready!");
  12:  
  13:          });
  14:  
  15:     
</script>
  11:  
  12:     
  13:  
  14:     <p>
  15:         <strong>Location</strong>
  16:         <button id="btnGeoLocation">Get Current Location</button><br />
  17:         
  18:  
  19:     </p>
  20:     <div id="locationResult"></div>
  21:  
  22: </body>

 

default.js code

   1: // For an introduction to the Blank template, see the following documentation:
   2: // https://go.microsoft.com/fwlink/?LinkId=232509
   3: (function () {
   4:     "use strict";
   5:  
   6:     WinJS.Binding.optimizeBindingReferences = true;
   7:  
   8:     var app = WinJS.Application;
   9:     var activation = Windows.ApplicationModel.Activation;
  10:  
  11:  
  12:     function $(element) {
  13:         return document.querySelector(element);
  14:     }
  15:  
  16:     function showLocation() {
  17:         navigator.geolocation.getCurrentPosition(function (location) {
  18:             $("#locationResult").innerHTML = "Latitude: <strong>" + location.coords.latitude + "</strong><br/>Longitude: <strong>" + location.coords.longitude + "</strong>";
  19:         }, function (err) {
  20:             $("#locationResult").textContent = "Error getting location";
  21:         }, { timeout: 30000, enableHighAccuracy: true });
  22:     }
  23:  
  24:     app.onactivated = function (args) {
  25:         if (args.detail.kind === activation.ActivationKind.launch) {
  26:             if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
  27:                 // TODO: This application has been newly launched. Initialize
  28:                 // your application here.
  29:                 $("#btnGeoLocation").addEventListener("click", showLocation, false);
  30:             } else {
  31:                 // TODO: This application has been reactivated from suspension.
  32:                 // Restore application state here.
  33:             }
  34:             args.setPromise(WinJS.UI.processAll());
  35:  
  36:            
  37:         }
  38:     };
  39:  
  40:     app.oncheckpoint = function (args) {
  41:         // TODO: This application is about to be suspended. Save any state
  42:         // that needs to persist across suspensions here. You might use the
  43:         // WinJS.Application.sessionState object, which is automatically
  44:         // saved and restored across suspension. If you need to complete an
  45:         // asynchronous operation before your application is suspended, call
  46:         // args.setPromise().
  47:     };
  48:  
  49:     app.start();
  50: })();

 

Create a Windows Store PhoneGap application

 

You need to turn on Location capabilities

 

Geolocation application screen.

 

Windows Store JavaScript Geolocation Application with WinJS.

Here is the code of the default.html file.

   1: <html>
   2: <head>
   3:     <meta charset="utf-8" />
   4:     <title>WinJS Demo App</title>
   5:  
   6:     <!-- WinJS references -->
   7:     <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
   8:     <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
   1:  
   2:     <script src="//Microsoft.WinJS.1.0/js/ui.js">
   1: </script>
   2:  
   3:     <!-- WinJSDemoApp references -->
   4:     <link href="/css/default.css" rel="stylesheet" />
   5:     <script src="/js/default.js">
</script>
   9: </head>
  10: <body>
  11:     <p>Content goes here</p>
  12:     <h1>WinJS for Windows 8 - Demo</h1>
  13:  
  14:         <p>
  15:         <strong>Location</strong>
  16:         <button id="btnGeoLocation">Get Current Location</button><br />
  17:         
  18:  
  19:     </p>
  20:     <div id="locationResult"></div>
  21: </body>
  22: </html>

 

Source code of the default.js  file is shown below.

   1: // For an introduction to the Blank template, see the following documentation:
   2: // https://go.microsoft.com/fwlink/?LinkId=232509
   3: (function () {
   4:     "use strict";
   5:  
   6:     WinJS.Binding.optimizeBindingReferences = true;
   7:  
   8:     var app = WinJS.Application;
   9:     var activation = Windows.ApplicationModel.Activation;
  10:  
  11:     function showLocation() {
  12:  
  13:         var geolocator = Windows.Devices.Geolocation.Geolocator();
  14:         geolocator.desiredAccuracy = Windows.Devices.Geolocation.PositionAccuracy.high;
  15:         geolocator.getGeopositionAsync().then(getCurPosHandler, errHandler);
  16:  
  17:  
  18:     }
  19:  
  20:     function getCurPosHandler(pos) {
  21:         document.getElementById('locationResult').innerHTML = "Latitude: <strong>" + pos.coordinate.latitude + "</strong><br/>Longitude: <strong>" + pos.coordinate.longitude + "</strong>";
  22:     }
  23:  
  24:  
  25:     function errHandler(e) {
  26:         document.getElementById('locationResult').innerHTML = e.message;
  27:     }
  28:  
  29:  
  30:     app.onactivated = function (args) {
  31:         if (args.detail.kind === activation.ActivationKind.launch) {
  32:             if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
  33:                 // TODO: This application has been newly launched. Initialize
  34:                 // your application here.
  35:                 document.getElementById('btnGeoLocation').addEventListener("click", showLocation, false);
  36:             } else {
  37:                 // TODO: This application has been reactivated from suspension.
  38:                 // Restore application state here.
  39:             }
  40:             args.setPromise(WinJS.UI.processAll());
  41:         }
  42:     };
  43:  
  44:     app.oncheckpoint = function (args) {
  45:         // TODO: This application is about to be suspended. Save any state
  46:         // that needs to persist across suspensions here. You might use the
  47:         // WinJS.Application.sessionState object, which is automatically
  48:         // saved and restored across suspension. If you need to complete an
  49:         // asynchronous operation before your application is suspended, call
  50:         // args.setPromise().
  51:     };
  52:  
  53:     app.start();
  54: })();

 

 

Conclusions:

It is a pretty easy to create Windows 8 applications with PhoneGap. Many people will ask - why PhoneGap after we are able to create Windows Store WinJS applications. The advantage of using PhoneGap e when you want an application to be compiled for different platforms (Windows 8 and various mobile platforms) without changes in your HTML and JavaScript code. If you need to create an application only for  Windows Store with JavaScript the  native choice will be to use WinJS except the case when you already have experience with PhoneGap for some of the mobile platforms. In all cases PhoneGap support for Windows 8 provides additional opportunities to create portable applications with JavaScript code. All WEB developers who know PhoneGap can easily  to create Windows Store applications without additional effort.

 

Source code of the Windows 8 PhoneGap geolocation application is available here.

Windows 8 sample application - geolocation with WinJS is available here.

You could download Visual Studio 2012 Windows Store PhoneGap template from this link.

 

Follow news from Infragistics for more information about new Infragistics events.

As always, you can follow us on Twitter @mihailmateev and @Infragistics and stay in touch on Facebook, Google+andLinkedIn!