Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Thursday, March 24, 2011

Bing Mobile HTML 5.0 Release and the Tale of 3 Devices

This morning when checking out the news feeds, I came across this article on how Microsoft released a Bing HTML 5.0 mobile client but Windows Phone 7 can’t use it since it doesn’t support HTML 5.0.  Well that certainly is true for the current version of WP7.

Let’s peal a layer off of that onion and ask the question is HTML 5.0 right for doing mobile sites?  

Just a point of order here, when we are talking about HTML 5.0 on the iPhone and Android, what we are really talking about is WebKit’s implementation of the soon to be standard, but I digress….

So here goes, here are pretty much three of the hottest devices right.  The righteous iPhone 4 on the left.  The high-end Android Nexus S on the right and finally the Windows Phone 7 HD7  in the middle. First off, let’s open up the browser on our devices and navigate to www.bing.com. it won’t look the same as on the Android and iPhone. Nope, it’s not running the HTML 5.0 version.

2011-03-24_0003

Ignoring the fact of the display size (Android has equal size screens) let’s take a look at what we see.  First off, the android rendering of the screen on the Android device only shows the top 1/4 of the Bing home page, ok, maybe there are some settings somewhere that I can change to send a different user agent string and get a better rendering, but hey I always keep coming back to my mom and how she would use a phone.

Phone Rings: 
Mom – my XYZ web page in the browser doesn’t look right.
Kevin – Oh that’s because you are…umm…let me see how to explain this…have your browser settings configured to render desktop pages rather than mobile ones.  Ok, here is what you have to do…first….
Mom – Never mind, I’ll just go back to my PC.

Now that we got past that, I guess it comes down to the look, and how the menus work.  On the iPhone I have a Metro style UI where I can move the menu up and down and click on an item.  On the HD7, I have a static list of the left where I can click on a link.  On the Android version if I play with it long enough I can get the same type of menu as on the iPhone.  Maybe you like the iPhone and Android (well if it rendered properly) version but it’s not like “OMG, the iPhone and Android are just fricken incredible and WP7 Sucks!”

So now let’s look at what happens when I actually do a search, I’m going to search for Pizza.

2011-03-24_0004

 

Ok the iPhone and Android render pretty the same thing. One point for HTML 5.0. Now we are getting somewhere. We have two WebKit browsers rendering the the search results in pretty much the same way, whoo-hoo! This is a major step forward right? (now think sarcasm). Again do you like the Android and iPhone versions or the WP7 version look better…personally I dunno, I guess the iPhone and Android have maps but I’ll contend that’s more a factor of just being newer than being HTML 5.0.

So in summary…cool Microsoft adopted HTML 5.0 for iPhone and Android versions, and now all is right with the world and everyone likes them again?  Nope they get the press saying…Microsoft bad because the new site won’t run on their flagship phone product.  Also this begs the question of what did HTML 5.0 really do for the site?  Let’s face it other than curing cancer, certain folks will have a predefined bias against anything Microsoft does.  Let’s leave the psychology of that discussion to a different day.

Enter native version of the Bing Application

2011-03-24_0005

For each of the platforms there is a native Bing application, for Android there is only some sort of version for the Far East only…go figure Android users don’t like bing, shocker there eh?  I did however find an application called NoBing…shocker again eh?

For Android and iPhone, these can be found in the marketplace.  For Windows Phone 7, launching it is as simple as pressing the hardware search key.  Now I’ve searched for Pizza again and retrieved the following results (yes the Android version is in some sort of Japanese or Chinese…no comment)

2011-03-24_0006

I’m not going to go into the details of the UX of the native applications compared to he HTML version, but try it for your self if you have one of these devices.  It’s not that difficult to figure out if the native version or the HTML version provides an over all better experience.

Being a mobile developer, one that focuses on cross platform development, I can’t certainly say that using a web approach for some applications makes sense.  Primarily if the application is small, and primarily read only.  Also, I think one thing isn’t mentioned very much, but it’s important to reiterate.  Both the iPhone and Android use flavors of web kit.  If you’ve done anything with targeting these mobile platforms, you know that they are extremely close but not identical.  Also it’s important to realize that different versions of both iOS and Android have different builds of web kit.  If you are pushing the technology, you’ll quickly find that the different versions evolve and things just break.  It will be very interesting to see the version of IE in WP7 VNext and see how the compatibility works between existing WebKit…er…I mean HTML 5.0 based sites and Microsoft’s implementation.  If history is any predictor, if it runs good on WebKit and Microsoft follows the standard to the letter and it doesn’t run good on WP7, I’ll give you one guess on which implementation will get more bad press.

Summary

So from a mobile perspective, what can you take away from this?  Again this is from a mobile expert where the majority of my experience is.

  • HTML 5.0 (or for right now WebKit) isn’t the end-all-be-all for everything.  The day of write once run everywhere isn’t just around the corner.
  • If you need to build a small mobile application that only targets the iPhone and Android, sure you can look at HTML 5.0, but can we please start calling it WebKit?  Also be creative, use some sort of frameworks to abstract the specific “stuff” you can really do some great things with this.
  • For a large mobile application and this one is…hear me now, believe me later…it will take much less time, you will have a much better user experience, considerably fewer support issues and finally maintenance and finding resources to work on your application will be much easier if you go with individual native applications targeting the platforms rather than trying to write one application that runs every where (or at least targets WebKit).  Trust me on this one…been there…done that…got the t-shirt.  Please before telling me I’m wrong, have a very much non-trivial application in production before commenting about what you could do.

-twb

Friday, August 21, 2009

Another Perspective on M-V-VM

I was tasked by a client to port a Windows Mobile application to run on many different platforms to include the iPhone, Palm Pre, Android, BlackBerry as well as desktop browsers.  To make this more interesting where the platform allows it, the application needed to run in an offline mode. 

They wanted me to look at building this on top of Google Gears to take advantage of its offline capabilities to include SQLite a local server to serve up web pages without an internet connection.  At first I was somewhat skeptical of the approach but once I started learning about the upcoming HTML 5.0 standards and the services it provided this approach seemed more and more practical.

So what does this have to do with Model View View Model?

This was a non-trivial application of approximately 120 screens and 80 or so tables so this wasn’t something I could just “hack” together. I wanted to implement this using some sort of pattern.  My basic requirement was that I wanted the simplest possible view (remember this needed to run on many different devices/platforms with different capabilities) so creating something where we can inject some HTML code that represents the view into the ViewModel and the ViewModel would take care of all the interactions and states of the control.  This way we can have a minimalist view for simplistic browsers such as Opera Mini that run on the BlackBerry, a decent good looking UI that will run on the iPhone, Palm Pre and Android and a full-featured UI that will run on the desktop.  The only thing that changes will be the HTML template.

There are some frameworks for M-V-VM that run on the desktop, some even run in Siliverlight.  My need was to build something that ran in the browser with JavaScript and HTML.  At this point I think the churn in my frameworks has pretty much died down and I can write what I learned and discuss my approach.

Before I get into the M-V-VM portion, let me list the 3rd party components that were used:

  1. JQuery – Used to manipulate the DOM
  2. Microsoft ASP.NET Ajax Library
  3. A modified version of Jay Kimble’s Class Compiler (simpler syntax for creating JavaScript classes)

Here’s a 50K ft level view of the interaction between the areas of the frameworksimage

Model

The model is used to encapsulate the idea of access to the data store.  My data access strategy is an interface that provides the mechanisms for CRUD.  This interface has been implemented on a Google Gears SQLite database, Safari/WebKit HTML 5.0 SQLite database as well as an AJAX connection that get’s it’s data from the server.  The models are fairly traditional in that they include all of the non-trivial business logic.

View

The views are built in HTML that rely heavily on CSS.  In addition we use attributes to describe how the View-Model should create and render the controls.  For example a drop down lists might be described as follows

<div id=’Module_View’>
  <div id=’ddlStatus’ TextField=’description’ ValueField=’id’
        DataValueField=’StatusId’ action=’statusChanged’>
    <label>Status</label>
  </div>
</div>

As you can see we are using HTML attributes to describe how the drop down should be populated as well as the action that should be invoked when the status changes.

Then for different templates we can create different views that our engine can pickup based upon browser type:

<div id=’Module_View_iPhone’>
  <div id=’ddlStatus’ TextField=’description’ ValueField=’id’
        DataValueField=’StatusId’ action=’statusChanged’>
    <label>Status</label>
  </div>
</div>

So far this has been working great, I haven’t had to include any JavaScript within my views.  All the JavaScript has been “attached” via JQuery in the View Models and primarily within the JavaScript controls.  I’ve also been able to do the vast majority of look-and-feel type of stuff in CSS.

View Model

When the html template as specified for the active skin is “injected” into the View-Model, the View-Model will create instances of JavaScript classes that encapsulate the idea of controls rendered properly on different platforms. 

this._ddlStatus = new Ctrls.DropDownList($(‘#ddlStatus’),$(‘#Module_View’));

So the ViewModel will create a new DropDownList instance after we use JQuery to find this html template and specification for the control.  The instance will then be ready to be data-bound and rendered on the form.  Note this is all happening in JavaScript within the browser.

In addition to creating fields from the HTML control templates our ViewModel is responsible for binding the data to those controls.  Each ViewModel requires a Bind method that expects a Model of the data that corresponds to that form.  It is the responsibility of the view model to gather any additional data required to populate the view.  This includes things like data sets for populating drop down lists.  It is also the responsibility of the ViewModel to manage state of the data on the view and do two-way binding.  There are two additional methods defined in our interface for the view, Validate and Save.  I like to think of the workings of the ViewModel as the private interface and code used to interact with the View.  The rest of the application does not directly act upon the ViewModel.  The rest of the application acts on the view and ViewModel by going through a Controller.

Controller

Here is where my implementation differs slightly from the traditional M-V-VM implementation.  For the way I’m building the application a controller seems to solve a number of problems and provides and fairly high-level interface when interacting with the View and ViewModel.  I would consider the Controller as a public interface to the View.   Each Controller that is implemented defines the following methods (note: bold methods are defined in an interface and must be present):

  1. Show(args) – Shows the view, args are view dependent but usually contain the ID for the primary data to be displayed as well any secondary information.
  2. Restore(launchArgs, returnArgs) – If this controller launches a child view and we return back to the calling controller.  The original calling args and optionally restoring args can be provided.
  3. Save() – If the frameworks requests that the current view data be persisted to  storage.
  4. SaveAndClose(callback) – If the frameworks requests the current view data be persisted to storage and the view closed.  If the ViewModel does not have valid data, the callback will return false and the form must not be closed.
  5. Cancel(callback) – Abort any changes, if the ViewModel can not be closed then the callback will return false and the form must not be closed.
  6. xxxxxAction – These are what are considered additional actions that can be invoked for the controller and are controller dependent.  These can either be generated by the View’s controls as in the case for a drop down list selection changing or a button press or come from the outside world as in a change of status of connectivity.  This also supports a fairly robust model for doing automated testing.

Very little code exists within the controller, the controller basically either passes on data/calls to the ViewModel or invokes business logic in the model and tells the UI to re-bind.

So in summary I look at the Controller as a high-level public interface to interact with the View through the private interface on the ViewModel.

ViewDispatcher

Everything in the application get’s routed through the ViewDispatcher.  The ViewDispatcher also runs in the browser via JavaScript.

The ViewDispatcher has methods such as:

      • ShowView(“[MODULE_NAME]”,”[VIEW_NAME]”,args (optional) ) – Shows a specific view within a specific module.  The ViewDispatcher is responsible for finding the view template in the ViewRepository, creating or loading and instance of the controller, cleaning up the previous view template.
      • PopView(return args (optional)) – Take the calling view off of a “return-stack” and call the Restore() method on the restored controller.
      • HandleAction(“[ACTION_NAME]”,args (optional)) – On the active controller, invoke a method with the name [ACTION_NAME]Action();
      • Save() – Call the save method on the active controller
      • SaveAndClose(returnArgs (optional)) – Call the SaveAndClose method on the active controller, if the callback from the controller returns true, then call PopView() with returnArgs if present.
      • Cancel() – Calls the Cancel method on the active controller.  If the callback from the controller returns true, then call PopView without any return arguments.

ViewRepository

At any one time a view may be active in the UI.  The ViewRepository is the complete set of views that may be called upon to active via the ViewDispatcher.  Once the ViewDispatcher has decided that view is no longer needed (usually replaced by a different one) the view will be placed back in the ViewRepository so it can be called upon again to be active.

Summary

So in summary at a high-level here are the different components that make up my frameworks and their responsibilities:

Models
  1. Models are fairly traditional, getters and setters for fields that make up the data in our system.
  2. Additional methods to handle business logic (both class and instance methods)
  3. 1:1 relationship between the model and database table
  4. Data access goes through an implementation of an interface.  The implementations that we currently have defined are:
    1. Google Gears SQLite (synchronous)
    2. Safari/WebKit HTML 5.0 SQLite (asynchronous)
    3. AJAX Service for devices not supporting (asynchronous) 
  5. Due to the nature of Safari and AJAX all data access (and any calls that at some point need to access data) are done asynchronously via call backs.
View
  1. Defines the presentation of the forms and data to the user
  2. Contains zero behaviors or JavaScript
  3. Presentation attributes are defined in CSS
  4. Uses attributes to be extracted at run-time with JQuery to define additional behaviors
  5. Are stored in the ViewRepository
  6. Are populated into the Active content region by the ViewDispatcher
  7. Are stored back into the ViewRepository by the ViewDispatcher
  8. Use the id format of [MODULE]_[VIEW] and optionally [MODULE]_[VIEW]_[SKIN]
  9. Does not support WYSIWYG
ViewModel
  1. Think of the ViewModel as the private interface to the view.
  2. The View is injected into the ViewModel
  3. Instance variables that correspond to the controls on the form are created from html tags and attributes
  4. Exposes a method named Bind(model) that has as it’s argument an instance of the model used to populate the view.
  5. Handles two way data binding between the model and view.
  6. Is responsible for pulling any additional data required to populate the view.  This could be lists to populate drop down lists or similar
  7. Contains all logic for managing the relationship between the model and the view.
  8. Handles simple interaction of controls, based upon state another control should be enabled/disabled
  9. Provides validation services, confirms that both the content of the view and the model are valid
Controller
  1. This is where my approach is varies from the standard model
  2. Think of the controller as the public interface for the view and the view model
  3. Provides methods named Show, Restore Save, SaveAndClose and Cancel (see above for more details)
  4. Also has methods named [ACTION]Action where these are the actions that should be invoked on the controller.  This is how external forces act upon the controller.
  5. This makes testing very simple
ViewDispatcher
  1. ViewDispatcher is implemented as a singleton
  2. The ViewDispatcher launches and displays views ShowView([MODULE],[VIEW],args)All interactions with controllers and thus with the ViewModel and View go through
  3. The ViewDispatcher through a HandleAction([ACTIONNAME]) method
  4. There is exactly one active controller at any one time.
  5. The ViewDispatcher has access to the ViewModel and ultimately the View through the active controller.

-ec