Offline iOS web app: loads my manifest, but doesn't work offline

37,773

Solution 1

I confirm that name 'cache.manifest' solved the offline caching problem in IOS 4.3. Other name simply did not work.

Solution 2

I found debugging HTML5 offline apps to be a pain. I found the code from this article helped me figure out what was wrong with my app:

http://jonathanstark.com/blog/2009/09/27/debugging-html-5-offline-application-cache/

Debugging HTML 5 Offline Application Cache by Jonathan Stark

If you are looking to provide offline access to your web app, the Offline Application Cache available in HTML5 is killer. However, it’s a giant PITA to debug, especially if you’re still trying to get your head around it.

If you are struggling with the cache manifest, add the following JavaScript to your main HTML page and view the output in the console using Firebug in Firefox or Debug > Show Error Console in Safari.

If you have any questions, PLMK in the comments.

HTH,
j

var cacheStatusValues = [];
cacheStatusValues[0] = 'uncached';
cacheStatusValues[1] = 'idle';
cacheStatusValues[2] = 'checking';
cacheStatusValues[3] = 'downloading';
cacheStatusValues[4] = 'updateready';
cacheStatusValues[5] = 'obsolete';

var cache = window.applicationCache;
cache.addEventListener('cached', logEvent, false);
cache.addEventListener('checking', logEvent, false);
cache.addEventListener('downloading', logEvent, false);
cache.addEventListener('error', logEvent, false);
cache.addEventListener('noupdate', logEvent, false);
cache.addEventListener('obsolete', logEvent, false);
cache.addEventListener('progress', logEvent, false);
cache.addEventListener('updateready', logEvent, false);

function logEvent(e) {
    var online, status, type, message;
    online = (navigator.onLine) ? 'yes' : 'no';
    status = cacheStatusValues[cache.status];
    type = e.type;
    message = 'online: ' + online;
    message+= ', event: ' + type;
    message+= ', status: ' + status;
    if (type == 'error' && navigator.onLine) {
        message+= ' (prolly a syntax error in manifest)';
    }
    console.log(message);
}

window.applicationCache.addEventListener(
    'updateready',
    function(){
        window.applicationCache.swapCache();
        console.log('swap cache has been called');
    },
    false
);

setInterval(function(){cache.update()}, 10000);

Solution 3

Sometimes an application cache group gets into a bad state in MobileSafari — it downloads every item in the cache and then fires a generic cache error event at the end. An application cache group, as per the spec, is based on the absolute URL of the manifest. I've found that when this error occurs, changing the path to the manifest (eg, cache2.manifest, etc) gives you a fresh cache group and circumvents the problem. I can vouch that all of our web apps work offline in full-screen with 4.2 and 4.3.

Solution 4

No offline web app (as of iOS 4.2) can run without an internet connection (which means Airplane mode, too) when using <meta name="apple-mobile-web-app-capable" content="yes" /> in the html head section. I have verified this with every example I've seen and the ones that use Safari to render the site work fine, but when you throw in that meta tag, it won't work. Try your app without it and you'll see what I mean.

Solution 5

I have found that clearing the Safari cache after enabling Airplane mode to be an effective way of testing whether the app is really functioning offline.

I have sometimes been fooled into thinking that the application cache was working when it wasn't.

Share:
37,773
Ken
Author by

Ken

Updated on November 04, 2020

Comments

  • Ken
    Ken over 3 years

    I'm writing a web app to be used offline on iOS. I've created a manifest, am serving it up as text/cache-manifest, and it usually works fine, when running inside Safari.

    If I add it as an app to my home screen, then turn on Airplane mode, it can't open the app at all -- I get an error and it offers to close the app. (I thought this was the entire purpose of an offline app!)

    • When I load the app a first time when online, I can see in my logs that it's requesting every page listed in the manifest.

    • If I turn off Airplane mode, and load the app, I can see the first file it's requesting is my main.html file (which is both listed in the manifest, and has the manifest=... attribute). It then requests the manifest, and all my other files, getting 200's for all (and 304's for anything requested a second time during this load).

    • When I load the page in Chrome, and click around, the logs show the only thing it's trying to reach on the server is "/favicon.ico" (which is a 404, and which I don't think iOS Safari tries to load, anyway). All of the files listed in the manifest are valid and served without error.

    • The Chrome inspector lists, under "APPLICATION CACHE", all the cached files I've listed which I expect. The entire set of files is about 50 KB, way under any limit on offline resources that I've found.

    Is this supposed to work, i.e., am I supposed to be able to create an offline iOS app using only HTML/CSS/JS? And where do I go about figuring out why it's failing to work offline?

    (Related but doesn't sound quite the same to me, since it's about Safari and not a standalone app: "Can't get a web app to work offline on iPod")

  • Ken
    Ken over 13 years
    This is a neat little bit of JS, but so far it hasn't helped me learn anything new. All the downloading/checking/idle in the log looks exactly as I'd expect.
  • Bert F
    Bert F over 13 years
    @Ken - sorry to hear that. it definitely helped me narrow down my errors (although it was still a pain to figure the exact cause of it). It also gave me some good feedback as to whether cache loaded/reloaded successfully (before knowing this, I would test offline after each and every change - after knowing this, I knew I needed to get the updateready event successfully before it was even worth trying it offline).
  • Ken
    Ken over 13 years
    Hmm. Do I need to worry about updateready and swapCache() and such? I was under the impression that, since I'm making an app which will live entirely offline (no server interaction at all, after the initial load), I could just put my filenames in the cache manifest, and that's it. Is it more complex than that in my case?
  • Ken
    Ken over 13 years
    Nope, as noted above (Safari is the same as Chrome, here, AFAICT) it never tries to request any resource (except /favicon.ico) from a desktop browser. The only time it does this is from iOS Safari, when in Airplane Mode (or when otherwise offline, presumably).
  • JakeCigar
    JakeCigar over 13 years
    I'd like to see the page. I run chrome/safari/firefox on my mac at home and iOS on iPhone and iPad.
  • Rowan
    Rowan over 13 years
    @pattern86 Interestingly I have a site here (still developing it, so can't share I'm afraid) which appears to work fine using <meta name="apple-mobile-web-app-capable" content="yes" /> . I can close the browser and the offline web app, switch on airplane mode, and still load the offline web app without an issue. Is there any other behaviour required to trigger this bug? I want to make sure we don't run into it in the wild...
  • Rowan
    Rowan over 13 years
    Curiously PieGuy works for me too. I'm on 4.2 (8C134) which is the 4.2GM. I'll try an update to 4.2.1 and see what happens :(
  • jsejcksn
    jsejcksn over 13 years
    @Rowan I am referring to offline web apps as ones that are added to the home screen. If you bookmark them in Safari and use them there, it should still work fine. Haven't tested this in iOS 4.3 yet.
  • Rowan
    Rowan over 13 years
    @pattern86 Aye, I also meant homescreen web apps. I've had a chance to test my site with 4.2.1 and 4.3 - in both cases, it's worked fine. So there seems to be some other effect at play here (the manifest is so sensitive to many things), but the manifest as a whole does appear to be able to function as intended.
  • jsejcksn
    jsejcksn over 13 years
    @Rowan I'm glad you got it to work! I'll give this a try sometime this weekend.
  • kliron
    kliron over 12 years
    +1 this worked for me - even though I could see that the iPad was fetching and using my previous manifest called offline.manifest
  • Fenton
    Fenton about 12 years
    +1 I have just tested this on a home-screen app on IOS 5.1.1. The main image was failing to cache, but removing this tag solved the problem.
  • Charles Clayton
    Charles Clayton about 10 years
    Removing that line fixed the problem for me too, but I'd really like to have both features...