Hi,

Jon and I talked quite a lot about a new architecture for this module, allowing it to be far better. Really.

Here is the explanation of the new architecture :

The overall architecture

Overall, the architecture will be in three parts : the mobile app, the phonegap module and submodules.

The mobile app

The mobile app will be rewritten. It will just be a login screen with some CSS for a nice layout, and a Javascript file. This javascript file will just do one thing : it will get redirect to the HTML of the app. That's it.

Here is an example of code for this :

I'll be using jQuery examples to make the code easier to read

$('#login-button').click(function() {
  // Auth stuff
  $.ajax({
    type: 'POST',
    url: drupal_url,
    data: {
      type: 'login',
      ...
    },
    success: function(data) {
      window.redirect(data.url);
    }
  });
});

The phonegap module

Of course, on the other side, there must be the phonegap module to answer this ajax call.

The phonegap module will do just one thing : it will login the user, and send back the URL of the app.

So this is kind of basic stuff, like :

/**
 * Takes care of the AJAX call.
 */
function phonegap_ajax() {
  // Login through webservice
  ...
  // Prints the response
  print json_encode(variable_get('theme_url', $url . 'basic');
}

The submodules

Now, these HTML files (let's call 'em "templates") can include some javascript and css files. The css files will take care of the layout, and the javascript files will take care of the functionalities. This is where the submodules get into the game. All the functionalities of the app will be in the JS files of the templates, and a submodule will be there on the server side. This means the submodule can retrieve some view, or just call any drupal function and print the result to the app (yay ajax!). Also, since the JS files will be executed on the mobile, all the camera/geolocation/etc stuff will be in those. Lastly, since Services is installed, the JS may not need PHP at all to call most of the Drupal functions.

Example of an HTML file :

<html manifest="cache.manifest"> <!-- This is the cache system. -->
<head>
...
<script type="text/javascript" src=""></script>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
<div id="basic" data-version="1">
  <div class="page" id="home">
    <h2>This is the app's HTML.</h2>
  </div>
  <div class="page" id="settings">
  </div>
</div>
</body>
</html>

The benefits of this architecture

There is only one drawback I can think of : the bandwidth. There will be more bandwidth used than currently.

But here are the benefits of this solution :

  • No mobile app update ever. The login screen and this JS file don't need to be updated.
  • It allows for a customization of the app to the extreme. Two apps using Phonegap module could be completely different.
  • Any developer can test in his browser if everything works fine. No need to install the app on his phone to try it out. His browser is fine.
  • Want to change the theme of your company? Sure, just do it. All your users will see the changes immediately.

Cache in manifest file

Everything should be accessed while being offline. Even though you connect and then go to the subway, you should still be able to navigate in your app. That's why we're using the manifest cache file to handle this.

Default framework

We're not using any framework in the app. The basic stuff will be handled by POJS. This means that any developer can use his own framework if he wants to, and this framework will be stored in localStorage, of course.

Handling the authentification

To handle sessions, there is the "bad way", checking that everytime the user wants to do something he is allowed to do it, or, I think, the "better way", using Services. Services allows to use a session system, and would also leverage the submodule code by having a lot of methods handled by default, like creating a node, getting a list of nodes, etc.
The first login will be using the module, while the app's calls won't need it.

Also...

There are some things to talk about.

  1. How many themes do we propose with the default installation? We must at least provide one, so that it works out-of-the-box. This'd be a good idea to propose two of them, so that developers/clients can see how different two themes can be.

There we go! Here is what we planned to do. If you have any idea, suggestion, opinion or whatever, please don't hesitate to say it!

Comments

ralt’s picture

Issue summary: View changes

typo

ralt’s picture

Issue summary: View changes

Adding a suggestion

ralt’s picture

Issue summary: View changes

Adding the theming out-of-the-box stuff.

ralt’s picture

Issue summary: View changes

Minor

ralt’s picture

Issue summary: View changes

Minor

ralt’s picture

Issue summary: View changes

Legal stuff.

jonanthony’s picture

Hi F,

I would like to discuss the idea that we pass "codelets" to the app in a weighted array eg

$phonegap_codelet['views_codelet'] = array(
        'html'      => 'views screen html',
        'css        => 'views screen css',
        'js'         => 'views screen javascript,
        'weight'   =>  20,
  );

$phonegap_codelet['camera_codelet'] = array(
        'html'      => 'camera screen html',
        'css        => 'camera screen css',
        'js'         => 'camera screen javascript,
        'weight'   => 25,
  );

The reason for this is that when we add submodules or themes, they can pass all the code they need to use in a single clean array. This would allow many sub modules to be added in relative harmony.

For the question of jquery mobile, I think we should have the source files within the app, but allow a configurable option as to whether they are enabled. The source files include sprites and other images. So far we have a method of transferring js,css and html, but not for images. Given the huge power of CSS3 to create gradients, perhaps this is enough?

I would very much like to maintain the ability of the app to function in a non networked state, so use of localStorage is probably essential.

J

ralt’s picture

Hi J,

First, about non-networked state, how do you auth people? I see why it'd be useful, but I don't see how to auth people if they don't have access to internet.

Also, I saw that we can store HTML (it's just a string), but storing files is more problematic (we may use Base64, but that means we have to find every file and encode it, then decode it when needed). Also, I don't know if by dynamically adding a string (from localStorage), the script tags process the GET requests.

So from what you mean, and for localStorage, I guess it'd be better to send HTML, CSS and JS scripts separately. Like the following :

/**
 * Takes care of the AJAX call.
 */
function phonegap_ajax() {
  $theme = './themes/' . variable_get('phonegap_theme', 'basic');
  $html = file_get_contents($theme . '/index.html');
  $script = array(
    file_get_contents($theme . '/script1.js'),
    file_get_contents($theme . '/script2.js')
  );
  $css = array(
    file_get_contents($theme . '/style1.css'),
    file_get_contents($theme . '/style2.css')
  );
  print json_encode(array(
    'html' => $html,
    'script' => $script,
    'css' => $css
  ));
}

Then, on the app's side, the JS file does this :

$.ajax({
  type: 'GET',
  url: bleh,
  success: function(data) {
    data = JSON.parse(data);
    $('body').html(data.html);
    localStorage.setItem('html', data.html);
    $.each(data.script, function() {
      $('head').append($('<script></script>')
        .type = 'text/javascript'
        .append(this.value)
      );
      localStorage.setItem('script' + this.key, this.value);
    });
    $.each(data.css, function() {
      $('head').append($('<style></style>')
        .type = 'text/css',
        .append(this.value)
      );
      localStorage.setItem('css' + this.key, this.value);
    });
  }
});

About your snippets, I don't see why you'd need this, since all your app is already in the template (with HTML & JS). Could you explain more what you mean?

ralt’s picture

Hi J,

I think I didn't explain myself very well. The PHP part of the submodule will just be there to handle AJAX calls, using the Drupal Framework. No more.

F

ralt’s picture

Issue summary: View changes

Precisions on debugging

ralt’s picture

Issue summary: View changes

Updating

ralt’s picture

Issue summary: View changes

Adding jQuery

ralt’s picture

Issue summary: View changes

Adding services

ralt’s picture

Issue summary: View changes

Adding cache

ralt’s picture

Issue summary: View changes

Taking off ajax

EvanDonovan’s picture

Has this architectural rewrite been completed?

Is there any documentation of how to use this to build an app?

I saw the documentation page that is linked from the project page, but it looks like it hasn't been updated since August. I am assuming the Phonegap source also hasn't been updated since August.

EvanDonovan’s picture

Has this architectural rewrite been completed?

Is there any documentation of how to use this to build an app?

I saw the documentation page that is linked from the project page, but it looks like it hasn't been updated since August. I am assuming the Phonegap source also hasn't been updated since August.

ralt’s picture

Hi,

I indeed forgot to update this page, sorry!

We are working on it whenever possible, although time is limited.

You can see this with the current issues, as well as looking at the 7.x-2.x branch on git where the latest code based on this architecture resides.

I'll update the first post asap.

EvanDonovan’s picture

Thanks, sounds great!

Since we are also potentially going to be working in this area (evaluating potential mobile architectures currently), I might want to connect with you sometime in a more real-time format - do you use IRC at all? I am EvanDonovan on there as well.

ralt’s picture

Check your mails! I've answered you giving out my skype :)

batje’s picture

This is a *real* good plan.

If in some way the FAPI can end up in the base module (so submodules can build forms for either webform, nodes or a custom form builder/datacollection tool) that would be wicked. Also offline storage of form results and a sync-mode of the app will be real great for datacollection. (I live in Uganda, so network availability is not a given)

Will watch this thread for updates, and go out to hunt for projects that could pay for implementing (parts of) this.

batje’s picture

Issue summary: View changes

Update