(Quick Reference)

3 Reference - Reference Documentation

Authors: 3.musket33rs

Version: 0.4

3 Reference

Because it's always better to illustrate with code, our reference manual is based on tutorial application ThreeCircles.

Hybrid Mobile App in minutes not days

Can you build your own version of Foursquare in minutes? Yes, you can. To survive offline your presentation logic should reside on the client. Using HTML5 power and jQuery mobile responsive UI your web app becomes Mobile. Ready to take the mobile challenges: geolocation, offline caching, data synchronization, server side event push, camera and packaging as Hybrid using PhoneGap. At the end of the session, you will have a clone of Foursquare on your mobile, with a REST backend in Grails running on the cloud. All that with one goal in mind: have fun!

3.1 Scaffolding

Read scripts description:
  • guide:html-generate-all
  • guide:html-generate-controllers
  • guide:html-generate-views

Refer to step1 of tutorial

3.2 How to customize MVC

3musket33rs includes a very easy custom MCV in JavaScript. As we've seen ealier this MCV catters for the default CRUD operations. For exemple see the update flow explained below:

Most of the time those CRUD operations could be enough for your need. Most of the times, even without adding new method you do need cutomization to write your view your own way.

Going back to the directory structure:

- web-app
  place-index.html
  - js
    - threecircles ----------------> Folder to customize
      configuration-bootstrap.js
      manager-bootstrap.js
      - bootstrap
        place-bootstrap.js ------> describe your domain class relationships 
      - controller 
        place-controller.js-------------> add methods other than CRUD
      - model 
        place-model.js -----------------> entry point to enhance model
      - view
        place-view.js ------------------> entry point to enhance view
    - grails.mobile -------------------> 3musketeers Mobile Framework
      - camera
      - feed
      - map
      - mvc
      - push
      - storage
      - sync

To customize your view, you will modify scaffolded code in:

  • js/threecircles/view/place-view.js

A default view is generated for you by the scaffolding. It uses jQuery mobile. It's up to you to customize it. For controller and model, if you only use CRUD server side operation, you don't need to extends Controller or Model.

Suppose now that we want to add a new verb, let's say for exemple: login. We need to extend Controller to do our cutom ajax call. Extending Controller could be enough if we don't need to store any data in the model.

If we want to add data to the model (like let's say the firstname of the user logged) we need to extend Model. In the directory structure, you will use the generated files (empty for now):

  • js/threecircles/view/place-model.js
  • js/threecircles/view/place-controller.js

Refer to step9 of tutorial for an exemple of implementation.

3.3 Geolocation

Double longitude latitude convention

By convention if you define 2 attributes: longitude and latitude as double, the plugin will know those attribute contains geolocation information. When doing a create, the browser will search your location.

class Place {
    String name
    Double latitude
    Double longitude
    static constraints = {}
}

with MongoDB indexing

When using MongoDB you can use a different convention to stick with MongoDB plugin. Location is expressed by a list of latitude and longitude. As shown below:

class Place {
    String name
	List location
	static mapping = {
   		location geoIndex: true
	}
    static constraints = {}
}

3.4 Offline support

To enable offline support at domain class level, open js/threecircles/bootstrap/place-bootstrap.js file and check offline is set to true.

threecircles.configuration.domain.push({
        name: 'place',
        view: {
			…
        },
        options: {
            offline: true,
            eventPush: true
        }

}

When on, each create/update/delete operation is saved on your local storage whether you are online or offline. when online the operation is also send to the server. When going under a tunel and loosing the connexion, your browser detects offline mode, 3musket33rs Feed service switch to offline mode and won't send the data to the server. Instead it offlinefeed will store the dirty state of the data on your device storage.

To render a visual effect we display the data using jQuery yellow thme, so you know you've lost the connexion and which data will need synchronization.

What will happen when back online? Keep cool, 3mukst33rs services provides data synchronization :-)

3.5 Synchronization

For now, Synchronization is in its simpliest model: unidirectional.

SyncManager implements one way synch with optimistic locking. Granularity is set to domain class. Using Grails instance version mechanism, when online mobile devices get notified (push notification) of other server updates and get a version of the doamain object.

When offline, modifications are stored locally. Back online, SyncManager triggers sync. Server can reject updates if the version number from the mobile device is different from the server one. At the moment, there is no smart fine-grained reconciliation.

html5-mobile-scaffolding v0.6 contains first implementation of Synch Manager. Later implementation will allows configuration of Synchronization stategies. More to come, stay tune…

3.6 Push notifications

When do you need it?

If you're working on a real-time multi-user application, like our ThreeCircles tutorial, you want to be notified when somebody else does a checkin. How can you do it nicely without polling your server?

Based on event-push Grails plugin (which uses Atmosphere framework on SSE protocol), html5-mobile-scaffoling provides support for server side push. By default, create/update/delete will raise anEvent on Groovy controller.

How to use it server side?

Event push are white listed in the file:

grails-app/conf/PlaceEvents.groovy

which contains the following decalaration:

events = {
    'save-place' browser:true
    'update-place' browser:true
    'delete-place' browser:true
}

Events are thrown in each controller like:

def save() {
      …
      def asJson = placeInstance as JSON
      event topic:"save-place", data: asJson.toString()
      …
    }

If you need to add new push event, you should add then to the white list and raise them when needed.

How to configure it on the client?

To enable push notification at domain class level, open js/threecircles/bootstrap/place-bootstrap.js file and check eventPush is set to true.

threecircles.configuration.domain.push({
        name: 'place',
        view: {
			…
        },
        options: {
            offline: true,
            eventPush: true
        }

}

PushManager is the client service implementation. In its first implementation PushManager is implemented as a broadcast. On receiving (for example) save-place event, Push Manager will update the data model (filtering its own eveant is done for you).

if offline support is on it will update local storage too. PushManager also enhances data model with a NOTIFED boolean attribute so you know this callback is coming from broadcast push notification.

Hybrid support

As shown in the the following tables:

Most modern browsers supports SSE but not the Android browser. As a result, current 3musket33rs Push notification is not available for Hybrid app.

3musket33rs team is writing a Cordova plugin to provide Push notification support on Hybrid Android applications. Stay tune.