iPhone 上的自定义 NSProtocol 和缓存问题

发布于 2024-08-24 18:51:16 字数 1961 浏览 13 评论 0原文

我的 iPhone 应用程序嵌入了一个 UIWebView,它通过我注册的自定义 NSProtocol 处理程序加载 html。

我的问题是,返回的 html 中引用的资源(也通过我的自定义协议处理程序加载)被缓存并且从不重新加载。特别是,我的样式表被缓存:

    <link rel="stylesheet" type="text/css" href="./styles.css" /> 

在 UIWebView 中加载 html 的初始请求如下所示:(

    NSString* strUrl = [NSMutableString stringWithFormat: @"myprotocol:///entry?id=%d", entryID ];
    NSURL* url = [NSURL URLWithString: strUrl];
    [_pCurrentWebView loadRequest: [NSURLRequest requestWithURL: url cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval: 60 ]];

请注意,缓存策略设置为忽略,并且我已经验证此缓存策略会延续到对页面资源的后续请求)初始加载)

协议处理程序从数据库加载 html 并使用如下代码将其返回给客户端:(

    // create the response record
    NSURLResponse *response = [[NSURLResponse alloc] initWithURL: [request URL] MIMEType: mimeType expectedContentLength: -1 textEncodingName: textEncodingName];

    // get a reference to the client so we can hand off the data
    id client = [self client];

    // turn off caching for this response data
    [client URLProtocol: self didReceiveResponse:response cacheStoragePolicy: NSURLCacheStorageNotAllowed];

    // set the data in the response to our jfif data  
    [client URLProtocol: self didLoadData:data];
    [data release];

请注意,响应缓存策略是“不允许的”)。

有什么想法可以让它不缓存我的 styles.css 资源吗?我需要能够在引用该文件的后续 html 加载中动态更改该资源的内容。

我认为清除共享 url 缓存会起作用,但事实并非如此:

[[NSURLCache sharedURLCache] removeAllCachedResponses];

确实有效但效率非常低的一件事是通过添加时间戳参数来动态缓存样式表的 url:

<link rel="stylesheet" type="text/css" href="./styles.css?ts=1234567890" /> 

为了使这项工作我必须加载我从数据库中搜索 html,搜索样式表的 url,并将其替换为随每个请求而变化的缓存清除参数。我宁愿不这样做。

我的假设是,如果我通过内置 HTTP 协议加载内容,就没有问题。在这种情况下,我猜测 UIWebView 会查看 NSURLHTTPResponse 对象的 http 标头中的任何 Cache-Control 标志并遵守它们。由于我的 NSURLResponseObject 没有 http 标头(它不是 http...),那么 UIWebView 可能只是决定缓存资源(忽略 NSURLRequest 缓存指令?)。

想法???

My iPhone app embeds a UIWebView which loads html via a custom NSProtocol handler I have registered.

My problem is that resources referenced in the returned html, which are also loaded via my custom protocol handler, are cached and never reloaded. In particular, my stylesheet is cached:

    <link rel="stylesheet" type="text/css" href="./styles.css" /> 

The initial request to load the html in the UIWebView looks like this:

    NSString* strUrl = [NSMutableString stringWithFormat: @"myprotocol:///entry?id=%d", entryID ];
    NSURL* url = [NSURL URLWithString: strUrl];
    [_pCurrentWebView loadRequest: [NSURLRequest requestWithURL: url cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval: 60 ]];

(note the cache policy is set to ignore, and I've verified this cache policy carries through to subsequent requests for page resources on the initial load)

The protocol handler loads the html from a database and returns it to the client using code like this:

    // create the response record
    NSURLResponse *response = [[NSURLResponse alloc] initWithURL: [request URL] MIMEType: mimeType expectedContentLength: -1 textEncodingName: textEncodingName];

    // get a reference to the client so we can hand off the data
    id client = [self client];

    // turn off caching for this response data
    [client URLProtocol: self didReceiveResponse:response cacheStoragePolicy: NSURLCacheStorageNotAllowed];

    // set the data in the response to our jfif data  
    [client URLProtocol: self didLoadData:data];
    [data release];

(Note the response cache policy is "not allowed").

Any ideas how I can make it NOT cache my styles.css resource? I need to be able to dynamically alter the content of this resource on subsequent loads of html that references this file.

I thought clearing the shared url cache would work, but it doesnt:

[[NSURLCache sharedURLCache] removeAllCachedResponses];

One thing that does work, but it's terribly inefficient, is to dynamically cache-bust the url for the stylesheet by adding a timestamp parameter:

<link rel="stylesheet" type="text/css" href="./styles.css?ts=1234567890" /> 

To make this work I have to load my html from the db, search and replace the url for the stylesheet with a cache-busting parameter that changes on each request. I'd rather not do this.

My presumption is that there is no problem if I were to load my content via the built-in HTTP protocol. In that case, I'm guessing that the UIWebView looks at any Cache-Control flags in the NSURLHTTPResponse object's http headers and abides by them. Since my NSURLResponseObject has no http headers (it's not http...) then perhaps UIWebView just decides to cached the resource (ignoring the NSURLRequest caching directive?).

Ideas???

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文