OK. Let’s say you’ve got some big, bulky, enterprisey application. This
application consists of an outer page (probably called index.jsp or something
like that) that never moves and assorted iframe tags for portlets and tabs.
The first through you probably have is “Ewwww, iframes, really?” You’re second
thought is probably that this is an application very much like the one Guy
works with. And, I hope, your third thought is one of sympathy for me since I
have to work on such an application. But I digress, como siempre.
Also, this application has session data that needs to be shared between
portlets and tabs and across tabs and all other sorts of complex interactions.
And, you want to do this client side for performance reasons. How, pray tell,
can you do this without writing spaghetti code?
If you’re really smart (and you are, right?) you’re probably just saying that I
should use HTML5 Local Storage and be
done with it. Great idea! I even wrote
ProtonDB, a framework to make this
sort of thing super-easy. But, alas, I’m stuck in Enterpriseland and HTML5 is
not permitted because it’s new and we fear newness because it is fraught with
risk and uncertainty.
But, I do have an elegant solution to the problem and the key lies in the fact
that the parent page doesn’t move. And since it doesn’t move it can simply hold
of code and import the .js file in all HTML pages (i.e. each portlet, tab, and
the outer page)
This code is simple and complex. Make sense of that! It assigns session if it
hasn’t been assigned yet. Since the outer page loads first, it gets defined
there initially because session doesn’t exist, and parent.session doesn’t
exist. All of the iframes then evaluate this same code and session doesn’t
exists but parent.session does. And, just in case someone has defined this
already we’ll always assign session to session if it exists.
To use the code simply modify the session object. For example:
Now I like to know what I’ve put in session so that I have a feel for how big
it is. So I actually use a slightly more complex pattern. I define a session
object with explicit accessors so the code tells me what’s stored there. And I
use a closure so no one can mess with my internal state and they have to go
through the defined session object. Here’s the code:
In this case, you would use the code like this:
A little extra code, sure, but I think the value add is worth it.
While I hope you don’t have to use this pattern and can instead just enjoy
HTML5 goodness, if you need it, here it is. Enjoy!
I’ve been working on a simple test case for a disconnected HTML5 application
for the iPhone/iTouch off and on for the past couple of weeks. It’s a points
calculator for a popular weight loss program who shall remain anonymous.
Anyhow, I thought this would be a handy tool for my wife and I and it would be
a nice and simple application to test a disconnected HTML5 application from the
So, I present to you Puntos. Full source
code is available on github but here’s how
I wrote it.
The application I developed is not remarkable. In fact, it is a simple math
problem. Peruse the source if you want details on how it works. The important
part is that it has the following files:
Just create the files for your application (or copy mine) and make it do what
Step #2: Make it iPhone Friendly
If you want it to be a cool iPhone HTML5 application, you have to provide an
icon from the iPhone desktop. You can do this by creating a file called
iphone-icon.png and placing it in the root of you project. This little file
is the favicon.ico of the Apple Mobile world. It is a 45 pixel by 45 pixel
PNG that your iPhone or iTouch will use if you decided to save a link to a
website on your desktop.
So, just create this file with your favorite image editing program (I used
Gimp) and save it with the other files.
Step #3: Add the Caching Magic
Here’s where the fun comes in. We can finally make the application
disconnected. The magic lies in an attribute on the html tag pointing the
browser to a cache.manifest file. This file then tells the browser which files
to cache and serve up when there isn’t a network connection.
So, simply add something like this to your HTML file.
This tells your browser to load up the file in the manifest attribute. The
filename can be anything but I would recommend having it end in .manifest as
this makes setting up the content type later much easier.
The cache.manifest is simplicity itself:
It simple contains the words CACHE MANIFEST at the top and lists all the files
needed by the application.
You might note that I did not include the index.html and you would be
correct. This is because the browser will assume that the file you loaded in
the initial request is part of the cache.manifest. No need to specify.
However, if you have several HTML files, you will need to specify them all in
your cache.manifest as there is no way to know which file you entered the
Step #4: Serving Up text/cache-manifest
It turns out that the cache.manifest file must be served up with a content
type of text/cache-manifest. It also turns out that most web servers aren’t
configured by default to do this since this is all bleeding edge and stuff.
So, you need to add it yourself. If you are using an apache server you can add
the content type to your .htaccess file. Add the following line and you
should be golden.
Step #5: Access the Application from Your iPhone & Troubleshoot
Your application should now work. So go access it. Then turn on Airplane Mode
and refresh the application. I should reload gorgeously. If it doesn’t, go back
and troubleshoot. But you knew that already.
One caveat though. I had a hell of a time trying to get the application to work
disconnected until I rebooted my iTouch (I don’t have an iPhone because I’m
lame). So, if everything looks like it should work but isn’t then you might
want to try turning off your iPhone by pressing and holding the power button
until it shuts down completely.
So, those are the steps I followed to get my first disconnected iPhone
Now go out and write me a game or something.
Also, for more information on HTML5 and disconnected applications check out
this fine website.
OK. Just spent 3 hours of my life that I will never get back trying to
troubleshoot and issue with Windows 7 and USB devices that I was having.
Figured it out so I thought I would share the problem and solution.
Whenever I would plug a new USB device in, it would not be detected by Windows.
Instead I would get a driver not found error and no amount of troubleshooting
on Windows’ part would help. This affected a new keyboard and mouse I purchased
(Logitech MK520) and an old headset that I had lying around. It was also
affecting my iPod but I didn’t realize that until after the fact.
In the case of my mouse and keyboard I would see in Device Manager a device
names USB Receiver with an annoyed looking yellow icon resting upon it. No
amount of messing with the icon helped.
All very frustrating because the hardware would detect the new keyboard and
mouse. When I booted the system and accessed the BIOS menu the keyboard worked.
The mouse was listed as detected. Everything seemed fine.
After much searching of the web in frustration. (Did I mention it was
frustrating) I finally found some people actually having the same problem. No
solutions, mind you, but the same problem. I determined from the gist of all
this posts that it was something to do with the USB drivers. Not the mouse
drivers or the keyboard drivers or the headset drivers but the core USB drivers
from Windows 7.
So I removed them all in Device Manager and rebooted so they could be
reinstalled. This worked – briefly. When the drivers were gone the mouse
started working. But Windows quickly fixed that and reinstalled the drivers and
I was back to a non-functioning mouse and keyboard.
Finally I came across some forum posts suggesting that
usb.pnf should exist in Windows\inf
and if they didn’t that would cause this issue. So, I Googled to find the files
and copied them in. Then I removed the annoyed USB Receiver driver and detected
My latest project is something that I have written three times: The Antichrist
The Antichrist Detector was conceived about 10 years ago when I stumbled upon
the entertaining idea that Bill Gates was the Antichrist. The idea was simple
and ludicrous. If you take the ASCII values of the name Bill Gates (uppercase
only please as any good numerologist will tell you) they add up the 663.
“But wait!”, you’re saying, “That doesn’t add up to 666?”
Correct. But Bill Gates full name is William Henry Gates III. So, Bill Gates
plus three does equal 666. It’s so obvious. How could you have not seen it?
Anyhow, this whole idea gave me a slightly twisted thought. You could automate
this. Write a simple program and feed it the phone book and out pops a list of
potential Antichrist. Not having a digitized phonebook handy I had another more
practical (in as much as any of this is practical) idea. Why don’t I put up a
website any let people enter their own names.
So, in 2000, I did. It was very successful and a lot of fun. It didn’t do much
but it generated a healthy amount of traffic and a lot of logs. In fact,
reading the logs was probably the best part about it. The emails I got,
however, were also very interesting. The vast majority of them were from
crackpots who thought I was serious. This greatly surprised but in hindsight,
it probably shouldn’t have.
My initial attempt was written in C++ and invoked via CGI. When I started
learning C# and .NET I decided to replatform it. So, version 2.0 was born.
Later, I moved to new hosting and no longer had .NET so I replatformed it again
and used it as an excuse to learn jQuery and PHP. 3.0 was born. In each
incarnation I added new features. 2.0 gained statistics. 3.0 gained an RSS
So, I am now staring down the barrel of The Antichrist Detector 4.0. This time,
techniques. I plan to also add features to this one as well. Most notably, you
will now be able to issue Antichrist Detections via Twitter!
Obviously, the Antichrist Detector has turned into a bit of a “Hello World”
application for me that I use to learn new technology. But, it’s also fun and I
hope that you can enjoy it as well.
I’ll post the link to the new version once it is somewhat available.