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

我正在写一个在 iOS 上离线使用的网络应用程序。我已经创建了一个清单,提供它作为 text/cache-manifest,它通常工作良好,当运行在 Safari。

如果我把它作为一个应用程序添加到我的主屏幕,然后打开飞机模式,它不能打开应用程序在所有-我得到一个错误,它提供了关闭应用程序。(我以为这就是离线应用程序的全部用途!)

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

  • 如果我关闭 AirFlight 模式并加载应用程序,我可以看到它请求的第一个文件是 main.html 文件(这两个文件都在清单中列出,并且具有 manifest=...属性)。然后它请求清单和所有其他文件,所有文件获得200(在这个加载期间第二次请求的任何文件获得304)。

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

  • Chrome 检查器列出了所有我希望列出的缓存文件。整个文件集大约为50KB,远远低于我所发现的离线资源的任何限制。

这是否应该工作,也就是说,我应该能够创建一个离线的 iOS 应用程序只使用 HTML/CSS/JS?那么我该怎么弄清楚为什么它在离线状态下无法工作呢?

(相关但对我来说不太一样,因为它是关于 Safari 的,而不是一个独立的应用程序: “ 不能让网络应用程序离线在 iPod 上工作”)

37980 次浏览

我发现调试 HTML5离线应用程序是一件痛苦的事情。我发现这篇文章中的代码帮助我找出了我的应用程序的问题所在:

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

调试 HTML5脱机应用程序缓存 作者: 乔纳森 · 斯塔克

如果你想提供离线访问你的网络应用程序,离线应用程序缓存可在 HTML5是杀手。然而,这是一个巨大的 PITA 调试,特别是如果你仍然试图让你的头周围。

如果您正在与缓存清单斗争,添加以下 JavaScript 到您的主 HTML 页面,并在控制台中使用 Firefox 中的 Firebug 或 Safari 中的 Debug > Show Error Console 查看输出。

如果你有任何问题,PLMK 在评论。

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

我有几个离线和离线工作的网络应用程序。

当我关闭机场模式时,我会收到一个对清单和其他一些文件的请求。

我没有收到图片、 JavaScript、 CSS 或缓存的 AJAX 文件的请求。

如果您看到对资源的请求,IOS 没有会缓存这些请求。

一般来说,Safari 对载货清单比较挑剔。

我建议你在电脑上试试 Safari。

当在 html 头部使用 <meta name="apple-mobile-web-app-capable" content="yes" />时,没有离线 web 应用程序(从 iOS 4.2开始)可以在没有互联网连接的情况下运行(也就是飞机模式)。我已经用我看到的每个例子以及使用 Safari 渲染网站的例子验证了这一点,但是当你添加 meta 标签时,它就不起作用了。试试你的应用程序没有它,你就会明白我的意思。

我有一个可能的解决方案——这看起来有点疯狂,但是这里要说的是... ... 我经常使用 cache.clear 和全屏应用程序(这里有一个测试,如果你需要的话: http://www.mrspeaker.net/2010/07/12/argy-bargy/-添加到主屏幕,然后打开飞行模式,它就会启动——至少在 iOS4.2.1中是这样的)

我发现一个奇怪的现象,有时候文件中的某些“元”信息似乎会因为被缓存而把它们搞乱——你有没有注意到在 bash 中,如果你使用“ ls”,一些文件(取决于你的颜色设置)会无缘无故地被高亮显示?文件可以有元数据,操作系统(我认为)自动添加-和有方法删除它... 我不记得为什么,但这里有一些更多的细节: 从 Snow Leopard 中的文件剥离元数据

有一天我抓狂了——并且拒绝放弃,因为我知道它应该可以工作... ... Chrome 说它加载了所有的文件,但是以一个普通的错误结束。最后,我用空白文件重新创建了项目结构,并复制/粘贴了内容。它起作用了——按照预期开始缓存!

当我看这些文件时,我注意到里面有一些元信息。我试着抹掉这些信息,原来的计划又成功了。我不确定这是否是它再次成功的原因——也许这只是一个巧合。

因为它起作用了,我没有想太多。几个月后,同样的问题再次发生,复制/粘贴技巧再次奏效。我当时很忙,所以没有进一步调查——但我发誓,下次再发生这种事时,我一定会查个水落石出... ..。但我还没必要。

不管怎样,很高兴我能把这句话写下来。

[更新: 几个月后-我无法复制这个,所以我不认为这是元数据]

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

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

我有时会被愚弄,以为应用程序缓存可以工作,其实并不能。

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

我已经写了一个离线应用程序,似乎仍然可以在4.2和4.2.1中工作; 这篇文章有点脏,但代码仍然可以运行:

Http://kentbrewster.com/backchannel/

Remy Sharp 有一个新的代码,在这里:

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

他的应用程序:

Http://rem.im/boggle/

在使用 Webserver 的 HTTP 身份验证让离线 web 应用在 iPhone/iPod Touch 上工作了几天之后,我发现了一些有用的东西:

  1. 在点击“添加到主屏幕”时,确保 Safari 位于 web 应用程序的 URL 根目录。我使用 jQuery Mobile,有时会添加带有“/# pageId”的链接。惹麻烦了。

  2. 以串行方式运行 Ajax 调用。这可能只有在你的 web 应用使用 HTTP 认证的情况下才是重要的,但是我的应用在页面加载时同时发出了大量的 Ajax 调用,导致应用挂在“ apple-touch-start-image”上。

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

  4. 在清单中使用“ NETWORK: n * n”。从我能够收集到的信息来看,这是一个针对“ CACHE:”部分中没有明确说明的任何内容的全面覆盖语句。使用 Chrome 来确保您的清单是正确的。查看 Chrome 的控制台是否有错误。

  5. 虽然没有直接关联,但是让我有点困惑,openDatabase.transactionous ()调用是异步的!这意味着,事务后的 JS 代码行(execute()error()success())将在 success()函数之前执行。

祝你好运!

自从我把我的 iPad 从4.2升级到4.3以来,我一直在与 iOS 4.3“没有离线缓存”的问题作斗争。我在这个网站的另一篇文章中看到,它在4.3.2版本中又能正常工作了。所以我又用 iPad 更新了一次,现在是 iOS4.3。但是仍然无法使离线缓存工作,直到我将清单文件重命名为“ cache.Manif”。然后缓存再次开始工作,我可以从主屏幕上运行我的 HTML5离线应用程序。我不需要把 Favicon.ico 放到缓存清单里。我还设置了全屏(将“ Apple-mobile-web-app-able”设置为“ yes”)。

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

我找到了这个似乎对我有用的解决方案,因为我在开发过程中也遇到了这个问题。到目前为止,这个修复程序对我和其他我要求测试它的人都很有效,我可以让它离线(在飞行模式下)运行,在缓存和其他东西之后离开主屏幕。我在我的网站上写了一篇关于它的文章:

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

  1. 删除主屏幕上当前的网络应用程序图标。
  2. 进入设置并清除 Safari 浏览器缓存。
  3. 双击 home 按钮打开多任务栏。找到 Safari,按住 把手指放在上面,然后退出。

请让我知道,如果这也为您工作! 祝你好运!

我已经写了一个应用程序,它通过移动浏览器工作良好,但当添加桌面... 不工作。我想苹果已经放弃了 IOS4,现在所有的努力都集中在 OS5上。羞耻: