Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the same codebase for phonegap and web?

Is it wise to use the same codebase for our mobile web app and phonegap app? They are meant to be similar, the phonegap version just lets us do more. Can we detect if it's not running on phonegap and sequester calls to the phonegap api or does it make more sense to separate them.

like image 522
fancy Avatar asked May 24 '12 04:05

fancy


Video Answer


2 Answers

Sure, you can use most of the same codebase. Some phonegap APIs are the same in html5 (for instance localStorage) so there's no difference in code there.

If you're using phonegap Build service, it will add the phonegap.js / cordova.js script file to your project root. Just include it in your html all the time. Then you can detect whether your application is running within phonegap:

var isPhonegap = function() {
  return (typeof(cordova) !== 'undefined' || typeof(phonegap) !== 'undefined');
}

if (isPhonegap()) {
  // phonegap.js/cordova.js exists.. now let's handle the onDeviceReady event
} else {
  // in-browser
}

If you need some common startup code, put it in a function and call this function from the onDeviceReady handler and the else block above.

If the phonegap api you're calling doesn't have the exact same name as the html5 one (because it has the Moz* or WebKit* prefix for instance), just wrap both inside a new name. For instance:

var requestFileSystem = (isPhonegap() ? requestFileSystem : window.WebKitRequestFileSystem);

If the phonegap API you're using really has no html5 equivalent, try to duplicate the functionality yourself in javascript if possible, otherwise you'll just lose the functionality in your browser. But make sure it degrades gracefully enough without that feature.

Note: to test the mobile devices features like accelerometer, geolocation, etc.. in your browser checkout the Ripple Chrome extension.

like image 84
chrisben Avatar answered Oct 02 '22 19:10

chrisben


I figured out a way to keep the web codebase intact...

The current problem with using the built in deviceready event, is that when the page is loaded, you have no way of telling the app: "Hey this is NOT running on an mobile device, there's no need to wait for the device to be ready to start".

  1. In the native portion of the code, for example for iOS, in MainViewController.m there's a method viewDidLoad, I am sending a javascript variable that I later check for in the web code, if that variable is around, I will wait to start the code for my page until everything is ready (for example, navigator geolocation)

    Under MainViewController.m:

    - (void) viewDidLoad
    {
        [super viewDidLoad];
        NSString* jsString = [NSString stringWithFormat:@"isAppNative = true;"];
        [self.webView stringByEvaluatingJavaScriptFromString:jsString];
    }
    
  2. index.html the code goes like this:

    function onBodyLoad()
    {
        document.addEventListener("deviceready", onDeviceReady, false);
    }
    
    function onDeviceReady(){;
        myApp.run();
    }
    
    try{
        if(isAppNative!=undefined);
    }catch(err){
        $(document).ready(function(){
            myApp.run();
        });
    }
    
like image 37
Juan Carlos Moreno Avatar answered Oct 02 '22 18:10

Juan Carlos Moreno