Feeds

How I wrote an iPhone application

An introduction to the world of mobile Web 2.0

Boost IT visibility and business value

Before our first function we created a few variables for later use:

var myRequest = new XMLHttpRequest();
var changeTo = "";
var home = 'http://www.theregister.co.uk';

JavaScript isn't strongly typed, but it should be clear that the latter two are strings and the first is an object-a-like thing we'll discuss later.

The StartUp function just checks to see if the change-text is set, and if not it asks the user what it should be set to. The functions for creating, changing and deleting cookies were lifted verbatim.

function startUp() {
  changeTo = readCookie("newName")
  if (changeTo == null) {
    changeTo = window.prompt("So what would better suit the iPhone?");
    createCookie("newName", changeTo, 1);
  }
  loadRegister(home);
}

The "loadRegister" function is run when the user clicks on a link (thanks to some later code) and checks to see if the user wants to leave The Register. If so, the page they want is loaded and the app ceases to run. Otherwise, the desired page is loaded using an XMLHttpRequest object-a-like.

function loadRegister(targetURL) {
  var targetDomain = targetURL.substring(targetURL.indexOf(".", 8)+1, targetURL.indexOf("/", 8));
  if (home.indexOf(targetDomain) == -1) {
    alert("Moving Off Site: " + targetDomain);
    parent.parent.location=targetURL;
  }
  myRequest.open("GET", targetURL);
  myRequest.onload = targetLoaded;
  myRequest.send();
}

Now we're in less-well-trodden territory, as XMLHttpRequest isn't as consistently supported as most of JavaScript, so documentation is sparse and contradictory in places. The basic function of an XMLHttpRequest is to load web pages, but it's worth noting that it can only load pages which come from the same server as the script itself - in this case "www.theregister.co.uk". Otherwise it just sits around doing nothing and reporting no error unless you're using desktop Safari with the JavaScript console turned on, an essential step which makes bug-chasing possible, if still horribly difficult. The line...

myRequest.onload = targetLoaded

...asks that once the desired page has finished loading the function targetLoaded should be run, this extracts the text and changes every instance of "iPhone" in the document (where preceded by, or followed with a space). It then opens, writes to, and closes the main frame to display the page before launching a truly horrible hack.

function targetLoaded() {
  var loadedSite = myRequest.responseText;
  loadedSite = loadedSite.replace(/iPhone /g, changeTo + " ");
  loadedSite = loadedSite.replace(/ iPhone/g, " " + changeTo);

  var loadedDocument = parent.frames[0].document;
  loadedDocument.open();
  loadedDocument.write(loadedSite);
  loadedDocument.close();

  setTimeout('pageLoaded()', 10000);
}

What we would like to do is run through each of the links on the page adding an "onclick" command to intercept mouse clicks. The problem is that we can't do that until the page has loaded, and the JavaScript event system isn't up to telling us when that's happened (as the browser considers the frame to have already loaded once and it's damned if it's going to trigger another "onload" event).

On desktop Safari we can use a hack with window.find to see if the end of our text has loaded, checking every few seconds to see if the words "Copyright 2007" are present, but that doesn't work on the iPhone for some reason. So our only alternative was to wait for ten seconds and then assume the text has loaded into the frame. This generally seems to work, but you wouldn't want to rely on it for anything mission-critical.

Once we think the whole document has loaded we can loop though and append our instruction to each link:

function pageLoaded() {
  for (i=0; i < parent.frames[0].document.links.length; i++) {
    parent.frames[0].document.links[i].onclick = linkClicked;
  }
}

When we were testing, the El Reg home page had 241 links on it, so it might be possible to count them (in order to avoid the wait-ten-seconds hack) but only if the number of links on the page could be guaranteed not to change.

This just left us with an old frames problem: the back button won't work, as it insists on considering the master frame to be the thing you want to back away from. We mucked about for a bit trying to get pages to load in different windows, which again works fine on the desktop but is verboten on the iPhone version of Safari, where only a user clicking can open a new window.

To solve the back-button problem we were forced to create our own back button, which does work, and was supposed to sit in a different frame at the bottom of the screen. But the iPhone Safari considers the whole frameset to be a single document, so when the user scrolls they scroll around the whole document rather than one frame: putting our toolbar at the bottom of the document rather than the bottom of the screen.

The essential guide to IT transformation

More from The Register

next story
6 Obvious Reasons Why Facebook Will Ban This Article (Thank God)
Clampdown on clickbait ... and El Reg is OK with this
So, Apple won't sell cheap kit? Prepare the iOS garden wall WRECKING BALL
It can throw the low cost race if it looks to the cloud
EE accused of silencing customer gripes on social media pages
Hello. HELLO. Can EVERYTHING EVERYWHERE HEAR ME?!
Time Warner Cable customers SQUEAL as US network goes offline
A rude awakening: North Americans greeted with outage drama
Shoot-em-up: Sony Online Entertainment hit by 'large scale DDoS attack'
Games disrupted as firm struggles to control network
BT customers face broadband and landline price hikes
Poor punters won't be affected, telecoms giant claims
Broadband slow and expensive? Blame Telstra says CloudFlare
Won't peer, will gouge for Internet transit
prev story

Whitepapers

A new approach to endpoint data protection
What is the best way to ensure comprehensive visibility, management, and control of information on both company-owned and employee-owned devices?
Implementing global e-invoicing with guaranteed legal certainty
Explaining the role local tax compliance plays in successful supply chain management and e-business and how leading global brands are addressing this.
Maximize storage efficiency across the enterprise
The HP StoreOnce backup solution offers highly flexible, centrally managed, and highly efficient data protection for any enterprise.
How modern custom applications can spur business growth
Learn how to create, deploy and manage custom applications without consuming or expanding the need for scarce, expensive IT resources.
Next gen security for virtualised datacentres
Legacy security solutions are inefficient due to the architectural differences between physical and virtual environments.