Me Want Cookie: Session Handling with NetBiscuits Mobile Web Apps

Shine was recently involved with helping a client bring an outsourced mobile web site in-house. The site was essentially a guide for browsing business and event information for cinemas, restaurants and bars in your area. Bringing this web site in-house was mainly an exercise in re-writing the outsourced instance as a component to the client’s own internally developed NodeJS/Express app server (currently used to serve their main – non-mobile – web site).

The NetBiscuits platform was used to handle all the device specific porting which allowed the development effort to focus almost entirely on business logic and backend data processing. The combined learning curve of NetBiscuit’s own markup language with Shine’s Jazz template system was simple enough to make the presentation layer development a breeze. This blog will talk about the process involved in developing for NetBiscuits and some of the problems and solutions encountered on the way.

So what is NetBiscuits?
NetBiscuits is a hosted platform technology that enables web apps to reach mobile devices. It’s essentially a knowledge base that maps mobile devices and their browsers to a presentation profile, translating your mobile site into the format expected by whatever mobile client that is making the request.

It’s worth noting that the concept of porting web content to mobile devices and their browsers is big. Seriously. The impact of standardized mobile web development is perhaps lost on those of us who’ve never worked in it before. Where common web development concerns itself with compliance across 4 or 5 main browsers, mobile web development must cater to hundreds. Even in the days when Nokia ruled the world the support and maintenance of mobile web apps for an ever-growing device list was not just for the final phase of a project but an ongoing full time job.

Maximizing your audience still means supporting the lowest denominator, but these days you can expect your low-end browsers to run javascript. This old school WAP and J2ME developer acknowledges that times have moved on but pays due credit to the people behind NetBiscuits and their mobile platform.

Working with NetBiscuits
You develop your mobile web app in mostly the same way as any other web app with the difference that instead of dynamically generating HTML you’re generating BiscuitML. Your production URL will point to your NetBiscuits account (hosted on their cloud) which in turn points to your app server.

simple_nb_flow
Simple Control Flow

For as long as your app server talks to the NetBiscuits platform in BML, NetBiscuits will talk fluently to all devices that hit your mobile site. This means your development efforts can focus purely on the business logic without the concern of tailoring content to multiple screen sizes and browser types.

Detailed NetBiscuits Control Flow
Detailed Control Flow

So what can you do with BML? Pretty much everything you can do with HTML. For most of the devices hitting your mobile site NetBiscuits will convert your BML to HTML. Writing markup in BML is done with Biscuit tags that comprise of familiar page elements such as; list, table, form, image etc. More specialised tags are available to handle ad-banners, analytics, maps and media. A script tag exists to provide various levels of javascript support ranging from handling browser events completely within the markup to simply relying on an external js file.

Challenges with Session Handling
Environmental constraints meant that client side session management was the only option available. This in turn meant that support for cookies and javascript was a requirement for any browser hitting the site. Cookies would store the user’s state code (see below) and the preferred list of cinema venues for returning movie times.

<TEXT>
    <richtext>
        Select your state:[br]
    </richtext>
    ...
    <richtext>
        <event type="onclick">
            <!-- Custom set cookie function -->
            <action eval="setStateCodeCookie('VIC');" />
            <action eval="return true;" />
        </event>
        [url="path/to/main/page/?{URLParams}"]VIC[/url]
    </richtext>
    ...
</TEXT>

Maintaining sessions within cookies is certainly made easier in the Tomcat/JSP model where the HTTPSession interface provides easy access to user data. In such a scenario, session data are largely managed by the server and a user is identified by a cookie-stored session id. In our instance we ended up pulling session data directly from cookies after discovering some limitations with BML.

Amidst the wealth of documentation for BML and its rich internet features there were examples of how to get/set/delete cookies from script tags. This led us to the false belief that a cookie could be interrogated and manipulated fully from within the markup. Wrong. BML’s getCookie function exists only to test the presence of a cookie, not to read/extract its data. Cookie handling was therefore relegated to an external js file which also meant taking control away from the markup for certain browser events. Specifically, the onclick event had to be hijacked from certain anchor tags to implement redirects for re-written URLs.

<TEXT>
    <richtext>
        Find Movies:[br]
    </richtext>
    ...
    <richtext>
        <event type="onclick">
            <!-- Override default behaviour and use
                 an externally defined custom handler
                 to perform redirect -->
            <action eval="getPreferredCinemasForMovieSearch('{URLParams}');" />
            <action eval="return false;" />
        </event>
        [url="#"]Browse by Cinemas[/url]
    </richtext>
    ...
</TEXT>

Hijacking the Onclick Event
Retrieving a user’s cinema preferences (above) is one example of URL re-writing trickery. Retrieving their state code is another. A state code would populate all URLs presented to the user. New users would have their state code persisted in URL parameters for the duration of their session. Returning users would need their session initialised by extracting their state code from the cookie.

Since cookie data wasn’t available at BML generation time, extraction would have to happen at URL click time. So this meant triggering a javascript function on the browser using the anchor tag’s onclick event.

Cookie handling at onclick
Cookie handling at onclick

Performing cookie data extraction at ‘click time’ effectively turns the handler function into an event-swallowing black hole, since it must also perform the page redirect leaving no control to pass back to the browser and it’s anchor tags. A consequence is that any URL parameters normally processed within the markup must now be passed to the javascript function for re-writing to the URL.

Ideals, Alternatives and Trade Offs
Relying on the BML to handle all things cookie/session related would have been the most ideal solution. URLs could have been re-written at BML generation time using cookie data without any javascript intervention. With the benefit of hindsight, the next best alternative would have been to utilize the onload event instead of hijacking the onclick event. This is because the onload event allows for the markup to retain control of its anchors – since re-writing happens well before URL click time.

This works fine for initialising a returning user’s state code since ALL URLs are modified with this data in the same way. However in situations where we needed to be more selective (extracting a user’s cinema preferences for only certain URLs), additional effort is required to identify/isolate the subset of URLs to operate on. Not all URLs need specific preference data appended to them. So the trade off is down to the assembly and redirect of URLs for a pre-determined anchor using the onclick method versus isolating a target set of anchors and appending data to an existing URL using the onload method.

<page>
    <script>
        <event type=”onload”>
            <!-- Append cookie data to a
                 target set of anchor tags -->
            <action eval="appendCookieDataToTargetURLs('{cookieName}',
                                                       '{targetId}',
                                                       '{URLParams}');" />
        </event>
    </script>
...
</page>

Conclusion
On the one hand it makes sense that BML can only provide superficial support for cookies given that its markup is never processed directly by the browser. On the other hand, if the NetBiscuits platform is communicating with client browsers and processing the BML on our behalf, could it not set its own session cookie and expose it through a set of functions within the markup? Where is NetBiscuit’s HTTPSession?! Perhaps the logistics of supporting potentially thousands of such sessions makes this concept infeasible.

To summarise, there may be further options available for enabling a mobile website that warrant a comparison but our experience with NetBiscuits was a happy and successful one. Cookie handling aside, the presentation layer development for our mobile app was super smooth. We also made use of a couple of the specialised tags for analytics and maps with relative ease.

The absence of full cookie support just means a little extra work. Perhaps we’ll see this built out in a future implementation of BML? In the meantime, its just old-school javascript know-how to enable cookie based sessions for your web apps. Of course, all this needs to be put in perspective with the main advantage provided by NetBiscuits: standardised mobile web development! Easy to overlook this significance when granted in such an accessible and ready-to-use format.

About Edward Calderon

Senior Consultant
This entry was posted in Javascript, Mobile and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s