(* We are almost a a year on from the original post so some of these things have improved – e.g. orientation is pretty much fixed in phonegap, but not sure if the Sencha issues are)
Firstly this post is not a rant and I remained convinced that Sencha Touch and PhoneGap are a great way to develop mobile – and I think that a cross device standard container to develop mobile apps is what we should all support.
There is almost nothing in the engineering of an html5 engine that could not be optimised for a native like experience – we are not their yet. Even the basics like scrolling a list, for example, are slower in a web view than native. Work like WebGL shows how close things are getting to native performance. The effort in creating that kind of standardised API – optimised per device is not easy; not least because it requires that competitors work with each other via w3c or OpenGL, webkit etc.
This post is about some of the trips and falls I took, and continue to take, whilst developing Money Toolkit with Sencha Touch and PhoneGap. I hope it can serve as a helpful alarm call for any others, like me, naively lured by the apparent silver bullet…
N.B. Some of what I have experienced is undoubtedly to my lack of knowledge; I’m sure the Sencha guys or Phonegap guys could put me straight. I’m not a stupid developer so it is likely that some of these issues, or my own mistakes, will be made by others, so even if the problems I write about are my own fault – detailing them here should still be helpful.
The title may present a slightly unfair impression. Not all of these issues have anything to do directly with the PhoneGap or Sencha Touch codebase, but are simply limitations of browsers, web-views and performance of mobile devices, though Sencha Touch / Phonegap framework does inherit those problems (and go to some lengths to work round the issues)
Things that work via the browser may break from in a UIWebView, which means they may work differently in phonegap (orientation is an example)
The side effect of this problem is that your queries in the Sencha Touch forums (see below) will often not get attention unless it is reproduceable outside of PhoneGap.
The issue below relates to how orientation is handled…
The first picture is after a couple of rotations in the simulator…

and this is after a couple of rotations on the device (screenshot from device added to simulator background to show the shift up)…

notice the shift – where the sizing and offset is confused by the status bar.
PhoneGap v 0.9.4 is broken (and despite an improvement so too is 0.9.5) but there are some patches and work arounds, there are sizing issues in Sencha Touch as well, see above.
First of all is the event ‘orientationchange’ or ‘orientationchanged’ ? There is some inconsistency in implementations – so be wary. Either way it does not get fired in the UIWebView.
Here is a good jumping off point to the solution… a thread on the Sencha Touch forum. If you look at some of the other solutions like I did you will end up with problems with resizing during orientation changes when the soft keyboards are displayed, amongst others.
Also the viewport sizing is suspect and inconsistent between the physical and simulated devices – see above.
Most differences are probably related to speed. See point 5 below – this can work in the simulator, but will fail on a device.
You can’t get away with just testing on a simulator.
The masks and boxes are not maintained in a managed stack – they are positioned in absolute layers (via css z-index) so a modal dialog box cant be shown on top of a loading mask.
If you mess with the z-orders in the default css (probably via compas compiling scss) then be aware of the knock on – for example the modal behaviour of the spinner selector can get hidden behind the mask.
Due to the implementation of this singleton the message box retains the size from its first drawing – doLayout does not work, the only thing to do is to get it to destroy itself each time it is shown – so it is less of a persistent singleton…
Expect to put something like this somewhere early on in your code
// this so that the messagebox is redrawn and resized on each showing
resetMsgBox = function() {
Ext.Msg = new Ext.MessageBox();
Ext.Msg.on({
hide: function(component) { component.destroy(); },
destroy: function(component) { resetMsgBox(); }
});
};
resetMsgBox();
Adding async behaviour like loading a store to initComponent – creates intermittent null element errors in the sencha touch library, (after the fact, it is kind of obvious this might cause problems)
So if the component or panel that you are init-ing is dependant on the result of the asynchronous behaviour – like an ajax call or local storage, you could be in trouble.
This stuff does work on a simulator or web browser based – but it is probably good luck that the callback happens fast enough for the init to be ok.
I’ve just thought – what I have not tried is calling the base class init in the async callback – that might work.
What i have done is now move all set up action to happen before initComponent.
Sencha touch has to turn the name value pair system of the browsers local storage into a database row type model to mach its store design.
You then have to make this behave like a name value pair – which means struggling with the way rows are id’d
your own localstorage wrapper class will be better for storing app settings in local storage – the native locastorage api is easy to work with.
Having said that if you want to bind your settings to a single form you may well be better off defining a model and a single row store to take advantage of the built in form behaviour.
You know fail early fail fast etc?, to which I add: fail visibly.
Sencha Touch in a browser is fine and will fail fast, your js console is perfect for showing exceptions, debugging, breakpoints etc..
wrapped up in PhoneGap you lose all of this – you have a console.log and console.error but all js exceptions are quietly swallowed – resulting in chunks of code not running after the exception with varying results, failing slowly.
To work round this you end up wrapping loads of your code in try catch blocks – a real pain – and still not the same as running in the browser. You may like me pepper the Sencha Touch library with console.log statements…
try {
me.login.showform();
} catch (ex) {
if (ex.message && ex.name) {
console.log("someMethod caught an exception of type " + ex.name + ": ", ex.message);
console.log(ex);
} else {
console.log("someMethod caught a poorly-typed exception: " + ex);
}
console.log(ex.stack);
}
Ugly, time consuming, hit and miss, but necessary!
I mentioned lists briefly in the intro but scrolling long lists in Sencha really suck on the devices, on a decent pc it’s fine.
Check out this thread, for something that could help…
(I’ve even submitted a pull request to Lioarlan’s promising extension for when you bind the data source later)
*Update* – Even with medium sized lists there is a problem with a laggy animation. I hope Sencha gets this fixed. In the mean time I have plugged in iScroll4, just in case, but that will need more wiring..
Demonstrated here…
Ok it may be unfair and unrealistic for me to want free support from the Sencha Touch forums, and PhoneGap group – the reality is the ST forums are pretty good and if you dig, you will find answers, but don’t expect your question to get answered – or looked at by the ST staff. They have their hands full with the paid support customers I guess.
Sencha Touch is still pretty new and we are all learning – so the forums are pretty much take, take, take – I have tried to answer as many questions as I have asked and share what I have learned but a lot of people have given more than they have taken and have lost enthusiasm… for example….
Sad!
My own defect report (which is not trivial to file accurately) has had no attention at all – it is a verifiable repeatable defect that is present in all their demos and my own app – they must have bigger priorities.
The PhoneGap google group is more responsive perhaps because there are still fewer users than Sencha Touch, but its still a hit and miss affair. they charge $250 for a basic support package , which does not appear to allow you any ‘support cases’ just a private forum and chat room with no guarantees, or a ‘pro’ package for $5,000 – holy shit – that’s most tiny startups out of the equation.
Sencha Touch support is based on an x-credits system and you appear to get a bit more for their introductory $299, like roughly 4 support calls with your x-credits.
There is a great blog post by Eric Boyer with some very useful advice regarding some more gotchas with Sencha Touch…
Sencha Touch Tips and Tricks
Pingback: Article: The Problem with Sencha Touch and PhoneGap | Money Toolkit « Raw Material