Wednesday, 27 February 2013

Launch a website as a mobile app using PhoneGap/Apache Cordova


How to launch a website as a mobile app using PhoneGap/Apache Cordova


I spent some time recently trying to find out how to launch my website as a mobile app.  The information was available around the internet but since it took me a while, I thought I'd collate it here in one simple post for anyone who wants to do the same

I decided to use Apache Cordova since it gave me the framework for developing an HTML5 site as a mobile app already, meaning all I really needed to do was plug my website into it.  Their getting started guide has good information on how to create a Cordova project - I used Android but you can use whatever means you wish

A basic Cordova app gives you a way to launch the app with an HTML page that you use to display your app contents.  The trick then is make the page load your website which you can do in one of 3 ways:

1. Package your site inside the app. This means it loads fast and without an internet connection.  The downside is you have to update and re-release the app whenever your website changes. It also needs to use relative paths since the root directory will be the mobile device's root directly, not the root of your site
2. Point the page at your remote website, which means changes are picked up immediately.  The downside is that it won't work if the phone has no internet connection
3. Do both and fall back to the local site if there is no network connection

Option 1 - Package your website inside the app

If you want to do option 1 (package your site with the app) you simply copy your entire site into the assets > www directory which will load your homepage as a local page (I think PhoneGap Build insists this is index.html, but if you're loading from code you just launch Cordova with that page name). Simple. You need not read on unless you're interested in option 2 or 3

Option 2 - launch your external website inside the app

To load a remote site, you need to load your homepage (or any page) using javascript from the html page that Cordova will open in your app.  This is relatively simple using basic javascript
window.location="http://your.website";

The recommended way to run javascript in a Cordova environment is to use Cordova's ondeviceready event which ensures it is loaded, which can be hooked into your page

document.addEventListener("deviceready", onDeviceReady, false); 
function onDeviceReady() {
    // Now safe to use the Codova API
window.location="http://your.website"; }

This is probably not strictly necessary for this javascript call, which is not using the Cordova API.  However I am using because it is needed for option 3

You also need to tell Cordova that it is safe to load your website in the cordova.xml properties (you can remove the subdomains part if you don't have any)
<access origin="http://your.website" subdomains="true"/>

At this point you are good to go!

Option 3 - launch your external website but fail back to local version

This option requires a little more work but gives you the advantage of displaying a set of files packaged with the app if there is no internet connection

Since you need the html page given by Cordova in assets > www you will need to copy your local site to a subdirectory (I've called it local), and do everything in option 2 to load the remote site

All you need then is to add some logic to decide whether there is an internet connection and act accordingly.  Fortunately Cordova gives us a solution to this

Firstly, add a javascript function to check the connection type

   function checkConnection() {
         var networkState = navigator.network.connection.type;
         var states = {};
         states[Connection.UNKNOWN]  = 'Unknown connection';
         states[Connection.ETHERNET] = 'Ethernet connection';
         states[Connection.WIFI]     = 'WiFi connection';
         states[Connection.CELL_2G]  = 'Cell 2G connection';
         states[Connection.CELL_3G]  = 'Cell 3G connection';
         states[Connection.CELL_4G]  = 'Cell 4G connection';
         states[Connection.NONE]     = 'No network connection';
       
         return networkState;
       
     }

Then add some logic around the window.location call to load the appropriate site

   function onDeviceReady() {
   var networkState = checkConnection();
 /* load local files if there is not network connection */
                  if (networkState == Connection.NONE) {
                      window.location="local/index.html";
                  } else {
              window.location="http://your.website";
                  }
   }

Again, you're good to go!

As an alternative to option 2 or 3 (I'll call it option 2a) you could use the connection type logic to display an error message so you don't attempt to load the external site when there is no connection eg:

   function onDeviceReady() {
   var networkState = checkConnection();
 /* load local files if there is not network connection */
                  if (networkState == Connection.NONE) {
                  navigator.notification.alert('This app requires an internet connection');
                  } else {
               window.location="http://your.website";
                  }
   }
I'm going to wrap a framework around this and release some instructions for non-developers to produce site launchers for mobile devices using PhoneGap build.  Watch this space

12 comments:

  1. This was a good suggestion that you put up here...dude…..hope that it benefits all the ones who land up here. 

    Edmonton Mobile App Development

    ReplyDelete
  2. I recently came across your blog and have been reading along. I thought I would leave my first
    comment. I dont know what to say except that I have enjoyed reading. Nice blog.
    I will keep visiting this blog very often.
    flights to Umrah
    cheap flight to jeddah
    flights to jeddah
    umrah jeddah flights
    umrah flights from London
    cheap flights to umrah

    ReplyDelete
  3. Trying to do step 2 here, but unsuccessful. Wondering if you could help me out really quick. I would greatly appreciate it.

    ReplyDelete
  4. Got it to work, minus the site styling. Shouldn't it be pulling in all the styling as well (using step 2)?

    ReplyDelete
  5. Hi, yes it should, it's just CSS so the styles should get pulled in from there. Are they hosted externally to your normal site, or in a subdomain? Could be the access origin

    ReplyDelete
  6. Hi,

    Thanks for the great tips. Exactly what i needed when i needed it!

    ReplyDelete
  7. Option 2 open browser and loads website. where did i go wrong?

    ReplyDelete
  8. Hi

    I'd probably need a bit more information than that but it could be that you didn't set the access origin, are pointing your launch file to the remote page instead of the local one, haven't set cordova up properly ... if you can provide your cordova.xml, local html code etc I might be able to help but otherwise that question is too vague

    Antony

    Antony

    ReplyDelete
  9. I have php scripts running back end of my mobile website ,is it possible to deploy my website as an app with option 2
    thanks in advance

    ReplyDelete
  10. Hi, no, cordova doesn't run PHP which is a server-side language I'm afraid
    Antony

    ReplyDelete