You'll be needing the Frost mobile ajax library. Unfortunately not yet available. Hmm, maybe I'll beat them to it. Their site design is nicer than mine though.
You'll also be wanting to read the Mobile Ajax FAQ.
And if you read German (which I can rather slowly) there's a useful site here: mobileajax.de
Wednesday, June 13, 2007
The Google Gears/iPhone speculation reaches fever pitch! It's off the chain!
Ian is still musing over how you'd get Google Gears on the iPhone. There is a project for Safari in the gears subversion repository and instructions on how to get it working in WebKit as a plug-in. Sadly the latest version fails to build and I don't do objective C so I'm a wee bit stuck. Looks like it might be time to pull out a textbook.
There's a much better summary of anything I can put together on the subject over here.
There's a much better summary of anything I can put together on the subject over here.
Tuesday, June 12, 2007
GooglePhone actually a software platform?
From the RegisterThis would make more sense, although I have also heard rumours that it's real and it's made of plastic and friends of friends have nearly touched it. The core bit of this wave of speculation is what Google Gears does in mobile. Opera have "endorsed it". Symbian is believed to be putting more or less the same functionality in the next OS release: cobble together an HTTP proxy and a database together with some scripting and you have a Gears clone. Mozilla like it but Minimo is still too big to play nicely in phones. I'd be very surprised if the iPhone doesn't have some cache magic in it.
It would be more sensible to keep it as a reference platform: Google stand to make more money out of extending the reach of their core business (that'll be small ads) than they do getting involved in hardware. Particularly phone hardware, which I have this horrible feeling Apple are about to discover is a horrendous business.
Working with intermittent connections is a big constraint on mobile applications, and it makes sense to cache information where possible. This isn't the best approach for information rich applications (working a day trader screen in Google Gears would be foolish) but standalone apps like Writely^H^H^H^H^H Google Docs don't actually need a network connection: they just need a storage of some variety.
I've just started this blog
I've just started this blog, but it's the culmination of about four years of thinking (!) about Javascript, web and mobile starting with XML Data Islands in Windows PocketPC. Consequently stuff's going to come out in a rather disordered fashion, so bear with me.It'll also be a while before I make it look nice.
A bit about me might help. I started building websites in 1995 and started building stuff for mobile in 2000, when I worked on a project for a long-gone company called NerveWireless (hello NerveWireless people). I've therefore been making things for smaller screens longer than I have for big screens, although I have kept both domains going.
I'm unusually excited about the possibilities of running proper web apps on mobile devices (Ajax makes more sense when reloading a page hurts as badly as it does on mobile). But coupled with that is the worry that, as happened with WAP, we'll try and shovel too much into the device and cripple ourselves before we've had a chance to prove the point. I've seen some very sexy demos for mobile Ajax but they aren't really usable. Therefore I guess the point of view I'm trying to push is pragmatic Ajax on mobile. But that's way too long for a blog title.
If you want to contact me, the email for the blog is mobileajax (on the domain) slackr.eu. Note the cunning disguise the @ has adopted there.
Safari and iPhone
Yesterday's Steve Jobs announcement was the sort of thing British politicians excel at: re-announcing things in a new way, so it looks like there's something new to report.We knew that the iPhone runs Safari. Therefore it isn't a huge surprise that Steve suggests that we develop apps for the iPhone using Ajax and HTML. What is surprising is that people should fall for the "iPhone is open to developers" schtick. Well, yeah! What will be interesting is whether we get Apple style widgets to play with or not.
As a side note, David Card rightly blogs that the release of Safari for Windows is designed to increase the developer pool for the iPhone. (Thanks to the rather more alert Ian Betteridge for drawing this to my attention).
And snapback sucks. There. I said something bad about Apple.
UPDATE: it looks like Mr Daring Fireball wasn't fooled...
Monday, June 11, 2007
Trimming it down to the bare essentials
One of the difficulties with getting acceptance for mobile Ajax is that Ajax is synonymous with hefty frameworks in the desktop world. Only last week the entire concept was dismissed out of hand by a colleague with the words "I tried it, but you had to load a 70K library to do it."There's nothing wrong with frameworks so long as you have a fat pipe and loads of memory to deal with it. I've lost count of the times prototype.js (which is indeed 70K) has saved my life.
But on a mobile device bandwidth and memory are typically scarce, so you'll be wanting to cut back on all the helpful features of things like prototype and stick to the core of Ajax.
The core of the Ajax technique is use of the XMLHttpRequest object. This lets you (as the name suggests) make HTTP requests out of the browser under Javascript control. It's almost as misnamed as AJAX itself: you're not constrained to XML. This opaque naming extends to the method names, as we'll see.
The way this works is as follows:
1. You create a new XMLHttpRequest object (new)
2. Tell it to open a URL somewhere (open)
3. Tell it to go off and fetch the url (send)
4. Wait for it to come back with something
The fourth stage is the trickiest as XMLHttpRequest expects you to find out what it's doing via an event handler called onreadystatechange. This reports four possible states and the one you'll be interested in state 4, which is the state signalled when the request has returned some data.
It's probably easier to explain with some code:
(These examples are from majax.js on my site: http://slackr.eu/m/ You might want to fire this up in a browser to see if it works: I've tested it in Opera 8.65 and S60 Browser, but your mileage may vary)
1. var req;
req is a global for now: as I work towards my own microframework for Ajax I'll encapsulate this properly, but it'll do.
2. var callback;
this is a global for the name of the function that will actually do some stuff on the page. I could just code this into the script below, but I'm trying to be a bit formal.
3. function _statechange() {
4. if (req.readyState == 4) {
5. processResponse(req.responseText);
6. }
7. }
Lines 3 to 7 are the function that reacts when onreadystate changes. I should have included some HTTP error checking, but this is an example...
8. function setCallback(myfunc) {
9. callback = myfunc;
10. }
This is the code I call in the page to register the handler that actually writes to the page
11. function processResponse(t) {
12. callback(t);
13. }
And the above passes control to the page
14. function ajaxRequest(method, url, async) {
15. req = new XMLHttpRequest();
16. req.onreadystatechange = _statechange;
17. req.open(method, url, async);
18. req.send();
19. }
And the above is the meat of the whole thing. It gets three arguments in line 14 - a method which is either "GET" or "POST", a URL to get the data from and a boolean that determines whether the request is asynchronous or not - e.g., whether it blocks any further interaction in the browser while it process. Fragmentation alert: I haven't yet been able to get the S60 browser to respond to synchronous events. That's probably okay, as you're unlikely ever to want to do it.
Line 15 gets us a new XMLHttpRequest and stores it in our global req variable. 16 registers the eventhandler with our function at line 3. Lines 17 and 18 prepare the request and send it.
When the request executes the onreadystatechange event fires once for open, once for sending and then fires when the server begins responding. Only when the server has indicated that it has finished does readystate 4 fire and we can process our response.
The response has a number of properties which I'll look it later but for now the only one we're interested in is req.responseText. Unsurprisingly this contains the response as a string - can't emphasise that enough. You can also extract the response as XML if you fancy some hardcore DOM hacking.
In the actual page, I set the callback that writes to the page to simply put responseText into a div as its innerHTML.
And that's it. The actual Ajax Javascript is 406 bytes.
The example code can been seen at
http://slackr.eu/m/src/majax.js.txt
http://slackr.eu/m/src/fx.js.txt
http://slackr.eu/m/src/ajax.html.txt
Sunday, June 10, 2007
First, the mobile web
Before we get in to mobile Ajax, it's probably worth reviewing the best practices for mobile web dev anyway. Mobile web is surprisingly close to web development in terms of technology; but the entire mobile experience is constrained by factors you just don't to worry about (as much) on the wired web.
Constraint one: teensy screens
My Nokia N70 has a maximum screen resolution of 176x208. The E65 I'm currently developing against is QVGA: 240x320 (yes, the smaller, horizontal, number comes first).
The fact that aspect ratio is portrait rather than landscape makes a lot of difference to the design of the page: you can't have a left hand nav, because there's no real estate on the left hand to put it in. When a vernacular three column web page is rendered on mobile the usual result is several screensful of top-nav, ads, left hand nav before you get to the content. The situation might be greatly improved if web developers put the content first in the document and decorated it with left nav etc using careful chosen floats. But they don't.
One approach that all mobile browser vendors try is to give you a virtual viewport that the page is rendered to. It's then up to the user to scroll around the screen and zoom in and out to get an overview. This is, to be frank, teh sux. You wouldn't want to watch a widescreen movie through a periscope; but most people are quite happy to watch the movie on a different aspect ratio when it's on TV. Movies were 16:9 and above and TVs 4:3 for years with no major conflict between creators and viewers; movie directors tended to stick stuff into the central safe area, and viewers learned that occasionally they'd just have to accept they could only see Clint Eastwood's nose. If web developers learned safe areas in the way that film and TV people did we would have less need for wholesale mobile repurposing.
Best practice one then is: design for the screen in hand and don't rely on the browsers rendering to stick all the information on screen.
Constraint two: fiddly nav
The Opera client on my N70 does a good job of dealing with links: by default the cursor jumps to only items on the page that are actionable. The S60 browser wants to be a computer and forces the user to use the four way joystick to mimic a mouse. Which means that some of the time you find yourself trying to get focus on a link that is about this size.
Best practice two then is BIG TARGETS. Actually that's a best practice for all interactive applications, web or mobile, but it's especially relevant for challenging environments like mobile. Most modern browsers react to onclick events on divs so why not make an entire div area active, with the a href included as a fallback for the minority who've actively turned javascript off?
Constraint three: awful networking stacks
The more I deal with the joy of TCP/IP over narrowband wireless the more I come to the conclusion that actually the wapforum guys were on to something. TCP/IP doesn't like dealing with laggy networks: it falls back into a conservative mode where it sends lots of little packets and acts suspicious without lots of confirming ACKs.
The upshot of all this is that loading a web page over wireless can take an awful lot longer than you'd think. The HTTP overhead can add 10 seconds or more to a simple request. The slightly counterintuitive result of this is that it matters less how big your images are, and more how many there are. A 400 byte piece of page furniture will load as quickly as a 3k equivalent, because the payload of the request actually executes quite quickly. It's the set-up and tear-down phases of the request that add time. 3G is particularly prone to this problem, which explains why "blistering 3G speeds" aren't.
Unfortunately, most mobile operators are run by engineers whose prime directive is to minimise network throughput, so mobile proxies tend to crush images into low quality JPEGs. This does sweet eff all for loading times, but gets them a gold medal for having "done something to enable the mobile internet".
So, best practice three is: no more than three or four images on a page. And make 'em big. (Tip: if you make an image bigger than it needs to be (say 320x480) and then scale it to the width of the screen you can ameliorate the effects of mobile proxies because the compression artefacts will be less visible. Not very nice for the user though.)
Constraint four: fragmentation everywhere
In mobile, no-one can agree on anything. Largely because they don't have to.
You're tied to the network your operator runs, the proxies they choose, and the choice of browsers is usually one. So there's no real competition to make anything better.
Typical example: Opera only renders CSS for a page if the CSS is presented to it with a media="handheld" attribute and value. The S60 Browser, on the other hand (because it thinks it's a computer), ignores any CSS in a "handheld" block. The same CSS works more or less identically on both browsers, but you have to waste your time doubling up. Putting both in - media="handheld, screen" works okay, but actually you probably want to distinguish between things with real screens (desktops) and the S60 Browsers, so you now need to do some server-side work to get the right look on each device. Thanks Nokia.
I'll be trying to tabulate the fragmentations I know about in future posts. Hope the above helps.
Subscribe to:
Posts (Atom)