HTML5 Offline Web Apps: Cache Manifest Gotchas Are Fun

Spent the last few days working on an iOS app, focusing on the iPhone. The goal was to make a simple HTML5 game that can be played offline, in Airplane Mode, etc.

Everything was working great. I got it on my phone & everything. Tested it on a bunch of other phones via willing victims (aka, family & friends). Then suddenly, the offline caching functionality broke. The app would load fine the first time, while online but then would fail to load again online or off.

On initial load Chrome’s console showed this:

Creating Application Cache with manifest http://myurlpath.com/my/app/path/sm2/simplegame2.appcache
Application Cache Checking event
Application Cache Downloading event
Application Cache Progress event (0 of 38) http://myurlpath.com/my/app/path/sm/images/1.png
Application Cache Progress event (1 of 38) http://myurlpath.com/my/app/path/sm/images/10.png
Application Cache Progress event (2 of 38) http://myurlpath.com/my/app/path/sm/images/card.png
Application Cache Progress event (3 of 38) http://myurlpath.com/my/app/path/sm/images/startstop3.gif
Application Cache Progress event (4 of 38) http://myurlpath.com/my/app/path/sm/images/plusminus2.gif
Application Cache Progress event (5 of 38) http://myurlpath.com/my/app/path/sm/images/pic3.png
Application Cache Progress event (6 of 38) http://myurlpath.com/my/app/path/sm/images/plusminus4.gif
Application Cache Progress event (7 of 38) http://myurlpath.com/my/app/path/sm/images/pic8.png
Application Cache Progress event (8 of 38) http://myurlpath.com/my/app/path/sm/images/time.png
Application Cache Progress event (9 of 38) http://myurlpath.com/my/app/path/sm/game.js
Application Cache Progress event (10 of 38) http://myurlpath.com/my/app/path/sm/game.css
Application Cache Progress event (11 of 38) http://myurlpath.com/my/app/path/sm/images/s.png
Application Cache Progress event (12 of 38) http://myurlpath.com/my/app/path/sm/images/8.png
Application Cache Progress event (13 of 38) http://myurlpath.com/my/app/path/sm/images/2.png
Application Cache Progress event (14 of 38) http://myurlpath.com/my/app/path/sm/images/5.png
Application Cache Progress event (15 of 38) http://myurlpath.com/my/app/path/sm/images/simplememory_icon.png
Application Cache Progress event (16 of 38) http://myurlpath.com/my/app/path/sm/images/startstop4.gif
Application Cache Progress event (17 of 38) http://myurlpath.com/my/app/path/sm/images/plusminus3.gif
Application Cache Progress event (18 of 38) http://myurlpath.com/my/app/path/sm/images/pic4.png
Application Cache Progress event (19 of 38) http://myurlpath.com/my/app/path/sm/images/startstop1.gif
Application Cache Progress event (20 of 38) http://myurlpath.com/my/app/path/sm/images/level.png
Application Cache Progress event (21 of 38) http://myurlpath.com/my/app/path/sm/images/found.png
Application Cache Progress event (22 of 38) http://myurlpath.com/my/app/path/sm/images/pic1.png
Application Cache Progress event (23 of 38) http://myurlpath.com/my/app/path/sm/images/blank.gif
Application Cache Progress event (24 of 38) http://myurlpath.com/my/app/path/sm/images/pic6.png
Application Cache Progress event (25 of 38) http://myurlpath.com/my/app/path/sm/images/9.png
Application Cache Progress event (26 of 38) http://myurlpath.com/my/app/path/sm/images/6.png
Application Cache Progress event (27 of 38) http://myurlpath.com/my/app/path/sm/images/simplememory_startup.png
Application Cache Progress event (28 of 38) http://myurlpath.com/my/app/path/sm/images/attempts.png
Application Cache Progress event (29 of 38) http://myurlpath.com/my/app/path/sm/images/3.png
Application Cache Progress event (30 of 38) http://myurlpath.com/my/app/path/sm/images/0.png
Application Cache Progress event (31 of 38) http://myurlpath.com/my/app/path/sm/images/startstop2.gif
Application Cache Progress event (32 of 38) http://myurlpath.com/my/app/path/sm/images/pic5.png
Application Cache Progress event (33 of 38) http://myurlpath.com/my/app/path/sm/images/plusminus1.gif
Application Cache Progress event (34 of 38) http://myurlpath.com/my/app/path/sm/images/pic7.png
Application Cache Progress event (35 of 38) http://myurlpath.com/my/app/path/sm/images/pic2.png
Application Cache Progress event (36 of 38) http://myurlpath.com/my/app/path/sm/images/7.png
Application Cache Progress event (37 of 38) http://myurlpath.com/my/app/path/sm/images/4.png
Application Cache Progress event (38 of 38) 
Application Cache Cached event  

all subsequent attempts to reload the page showed this confusing message in the console:

Document was loaded from Application Cache with manifest http://myurlpath.com/my/app/path/sm2/simplegame2.appcache
Application Cache Checking event
x GET http://myurlpath.com/my/app/path/sm2/game.css 
x GET http://myurlpath.com/my/app/path/sm2/game.js 
x GET http://myurlpath.com/my/app/path/sm2/images/blank.gif 
x GET http://myurlpath.com/my/app/path/sm2/images/card.png 
x GET http://myurlpath.com/my/app/path/sm2/images/startstop1.gif 
x GET http://myurlpath.com/my/app/path/sm2/images/startstop4.gif 
x GET http://myurlpath.com/my/app/path/sm2/images/level.png 
x GET http://myurlpath.com/my/app/path/sm2/images/10.png 
x GET http://myurlpath.com/my/app/path/sm2/images/plusminus3.gif 
x GET http://myurlpath.com/my/app/path/sm2/images/4.png 
x GET http://myurlpath.com/my/app/path/sm2/images/plusminus1.gif 
x GET http://myurlpath.com/my/app/path/sm2/images/time.png 
x GET http://myurlpath.com/my/app/path/sm2/images/s.png 
x GET http://myurlpath.com/my/app/path/sm2/images/attempts.png 
x GET http://myurlpath.com/my/app/path/sm2/images/found.png 
Application Cache NoUpdate event

It was a simple error. I changed my server’s directory but totally forgot to update the paths in my CACHE MANIFEST file to reflect this (duh!), so the app would load once and then fail every time after the Google Chrome’s console showing a failed “GET” request on a bunch of files at the top of my manifest. Specifically, I forgot to change this path: “http://myurlpath.com/my/app/path/sm/game.css” to this “http://myurlpath.com/my/app/path/sm2/game.css”. Manifest-Validator.com did not show me any error (naturally, it wouldn’t be able to detect human stupidity). Manifest files don’t provide anything like compiler warnings, so little things like this, even something like a hidden character for a line break can screw things up easily. A similar error, only involving case sensitivity of manifest files is described in the solution here.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s