离线iOS网络应用程序:加载我的清单,但不能脱机工作

时间:2010-12-05 23:22:52

标签: html5 ios ios4 mobile-safari offline

我正在编写一个可在iOS上离线使用的网络应用。我创建了一个清单,我将其作为text/cache-manifest提供,并且在Safari中运行时通常可以正常运行。

如果我将其作为应用程序添加到我的主屏幕,然后打开飞行模式,它根本无法打开应用程序 - 我收到错误,它提供关闭应用程序。 (我认为这是离线应用程序的全部目的!)

  • 当我第一次在线加载应用时,我可以在我的日志中看到它正在请求清单中列出的每个页面。

  • 如果我关闭飞行模式,并加载应用程序,我可以看到它请求的第一个文件是我的main.html文件(它都列在清单中,并具有manifest=...属性)。然后它会请求清单和我的所有其他文件,为所有文件提供200个(对于在此加载期间第二次请求的任何内容,304)。

  • 当我在Chrome中加载页面并点击时,日志显示它在服务器上尝试访问的唯一内容是“/favicon.ico”(这是404,我不知道认为iOS Safari试图加载,无论如何)。清单中列出的所有文件都是有效的,并且没有错误地提供。

  • Chrome检查员在“APPLICATION CACHE”下列出了我所列出的所有缓存文件。整个文件集大约为50 KB,在我找到的离线资源的限制下。

这应该有用,即我是否应该只使用HTML / CSS / JS创建一个离线iOS应用程序?我在哪里弄清楚为什么它无法脱机工作?

(相关但对我来说听起来不一样,因为它是关于Safari而不是独立应用:“Can't get a web app to work offline on iPod”)

13 个答案:

答案 0 :(得分:22)

我确认名称'cache.manifest'解决了IOS 4.3中的离线缓存问题。其他名称根本不起作用。

答案 1 :(得分:7)

我发现调试HTML5离线应用程序很痛苦。我发现本文中的代码帮助我弄清楚我的应用程序出了什么问题:

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

  

调试HTML 5离线应用程序缓存   作者:Jonathan Stark

     

如果您希望提供对Web应用程序的离线访问,则HTML5中提供的脱机应用程序缓存是杀手锏。然而,它是一个巨大的PITA进行调试,特别是如果你仍然想要了解它。

     

如果您正在努力使用缓存清单,请将以下JavaScript添加到主HTML页面,并使用Firefox中的Firebug或Debug>在控制台中查看输出。在Safari中显示错误控制台。

     

如果您有任何疑问,请在评论中注明PLMK。

     

HTH,
  Ĵ

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);

答案 2 :(得分:5)

有时,应用程序缓存组在MobileSafari中进入错误状态 - 它会下载缓存中的每个项目,然后在最后触发通用缓存错误事件。根据规范,应用程序缓存组基于清单的绝对URL。我发现当发生此错误时,更改清单的路径(例如,cache2.manifest等)会为您提供一个新的缓存组并避免出现问题。我可以保证我们所有的网络应用程序都可以全屏离线工作4.2和4.3。

答案 3 :(得分:3)

在html head部分中使用<meta name="apple-mobile-web-app-capable" content="yes" />时,没有离线网络应用程序(从iOS 4.2开始)可以在没有互联网连接的情况下运行(这也意味着飞行模式)。我已经用我见过的每个例子验证了这个,并且使用Safari来渲染网站的工作正常,但是当你抛出那个元标记时,它将无法工作。试试你的应用程序没有它,你会明白我的意思。

答案 4 :(得分:3)

我发现在启用飞行模式后,清除Safari缓存是测试应用程序是否真正脱机运行的有效方法。

我有时会误以为应用程序缓存在没有的时候正在运行。

答案 5 :(得分:2)

自从我将iPad从4.2更新到4.3.1后,我一直在努力解决这个iOS 4.3“无离线缓存”问题。我在本网站的另一篇文章中看到它在4.3.2中再次运行。所以我再次通过iPad更新,现在更新到iOS 4.3.3。但是在我将清单文件重命名为“cache.manifest”之前,仍然无法使脱机缓存工作。然后缓存再次开始工作,我可以从主屏幕运行我的HTML5离线应用程序。我不需要将favicon.ico放入缓存清单中。而且我也全屏显示(将“apple-mobile-web-app-capable”设置为“是”)。

答案 6 :(得分:1)

我有几个离线工作和在线/离线网络应用。

当我关闭机场模式时,我收到了清单和其他文件的请求。

我没有获得图像,JavaScript,CSS或缓存的AJAX文件的请求。

如果您看到有关资源的请求,则IOS 不会将其缓存。

一般情况下,Safari的清单更加挑剔。

我建议您在计算机上试用Safari。

答案 7 :(得分:1)

我有一个潜在的解决方法 - 它似乎有点疯狂,但是这里...我使用cache.manifest和全屏应用程序(如果你需要,这里是一个测试:http://www.mrspeaker.net/2010/07/12/argy-bargy/ - 添加到主屏幕,然后打开飞行模式,它启动 - 至少,从iOS 4.2.1开始)

我发现一个奇怪的事情是,有时似乎文件中的某种“元”信息会使它们被缓存 - 你有没有注意到在bash中如果你做了一些“ls”的文件(取决于在你的颜色设置上)没有明显的原因突出显示?文件可以包含操作系统(我认为)自动添加的元数据 - 并且有一些方法可以删除它...我不记得为什么但是这里有更多细节:Strip metadata from files in Snow Leopard

有一天撕掉我的头发 - 拒绝放弃,因为我知道它应该有效... Chrome说它加载了所有文件,但以一般错误结束。最后,我用空白文件重新创建了项目结构,并将内容复制/粘贴。它工作 - 开始缓存,因为它应该!

当我看到文件时,我注意到有一些元信息。我尝试擦除此信息,原始项目再次工作。我不确定这是它再次起作用的原因 - 也许这只是一个巧合。

因为它有效,所以我没有想太多。几个月后再次出现同样的问题,复制/粘贴技巧再次起作用。我很忙,所以我没有进一步调查 - 但发誓我会在下次发生的时候到达底部......但我还没有去过。

呼。无论如何,很高兴我能把它写在某个地方......

[更新:数月和数月之后 - 我无法重现这一点,所以我不认为这是元数据]

答案 8 :(得分:1)

我今天在iOS 4.3上遇到了同样的问题。我能够通过添加favicon.ico文件并将其添加到清单来解决问题。

答案 9 :(得分:1)

我写了一个似乎仍然适用于4.2和4.2.1的离线应用程序;帖子有点尘土飞扬,但代码仍在运行:

http://kentbrewster.com/backchannel/

Remy Sharp有一个较新的帖子,代码也可以,这里:

http://remysharp.com/2011/01/31/simple-offline-application/

他的应用程序:

http://rem.im/boggle/

答案 10 :(得分:1)

在使用网络服务器的HTTP身份验证使得脱机网络应用程序无法在iPhone / iPod Touch上工作几天之后,我发现了这些有用的小块:

  1. 点击“添加到主屏幕”时,确保Safari位于网络应用的网址根目录下。我使用jQuery Mobile,有时添加链接“/#pageId”。造成麻烦。

  2. 串行运行Ajax调用。这可能仅在您的Web应用程序使用HTTP身份验证时很重要,但我的应用程序在页面加载时并行触发了大量的Ajax调用,这导致应用程序挂起“apple-touch-startup-image”。 / p>

  3. 离线时Ajax调用“成功”(至少使用Prototype.js)。测试Ajax响应中的实际数据,而不仅仅是HTTP状态。我用它来测试显示缓存(SQL)或实时数据。

  4. 在清单中使用“NETWORK:\ n * \ n”。根据我的想法,对于“CACHE:”部分中没有明确说明的内容,这是一个包罗万象的声明。使用Chrome确保您的清单正确无误。查看Chrome的控制台是否有错误。

  5. 没有直接关系,但是让我吵了一下,openDatabase.transaction()调用是ASYNCHRONOUS!意思是,事务(execute()error()success())之后的JS代码行将在success()函数之前执行。

  6. 祝你好运!

答案 11 :(得分:1)

我发现这个解决方案似乎对我有用,因为我在开发过程中遇到了这个问题。到目前为止,这个修复程序对我来说也很好,而且对于我要求测试它的其他人来说,我能够让它在离线(飞机模式)下运行并在缓存后等主屏幕上运行。我在我的网站上写了一篇关于它的帖子:

http://www.offlinewebapp.com/solved-apple-mobile-web-app-capable-manifest-error/

  1. 删除主屏幕上的当前网络应用程序图标。
  2. 转到设置并清除Safari浏览器缓存。
  3. 双击主页按钮以打开多任务栏。找一个Safari,拿着你的 用手指向下,退出它。
  4. 如果这对您有用,请告诉我!祝你好运!

答案 12 :(得分:1)

我已经编写了一个应用程序,它可以通过移动浏览器正常工作,但是在添加桌面时......不起作用。我猜苹果已经放弃了IOS4,现在所有的努力都在OS5上。惭愧:(