菜鸟教程小白 发表于 2022-12-13 07:35:44

ios - 如何使用 NSURLCache 缓存由 NSURLProtocol 提供的内容


                                            <p><p>我编写了一个 <code>NSURLProtocol</code>,它将检查出站 <code>http</code> 请求与 URL 到本地路径映射的 <code>plist</code> 并提供本地内容,然后使用 <code>NSURLCache:</code></p> 缓存它

<pre><code>- (void)startLoading
{   
    //Could this be why my responses never come out of the cache?
    NSURLResponse *response =[initWithURL:self.request.URL
                                                      MIMEType:nil expectedContentLength:-1
                                              textEncodingName:nil];

    //Get the locally stored data for this request
    NSData* data = [ getLocallyStoredDataForRequest:self.request];

    //Tell the connection to cache the response
    [ URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];

    //Have the connection load the data we just fetched
    [ URLProtocol:self didLoadData:data];

    //Tell the connection to finish up
    [ URLProtocolDidFinishLoading:self];
}
</code></pre>

<p>我将可以提取本地数据的次数限制为一次。第一次获取它的意图将来自 <code>NSBundle</code>,但此后它将使用库存 <code>NSURLCache</code> 来检查它是否应该来自 <code>NSURLCache</code> strong>缓存</strong>或<strong>网络</strong>:</p>

<pre><code>+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    //Check if we have pre-loaded data for that request
    ELAPathSubstitution* pathSub = [ pathSubForRequest:request];

    //We don&#39;t have a mapping for this URL
    if (!pathSub)
      return NO;

    //If it&#39;s been fetched too many times, don&#39;t handle it
    if ( &gt; 0)
    {
      //Record that we refused it.
      ;
      return NO;
    }

    //Record that we handled it.
    ;
    return YES;
}
</code></pre>

<p>可悲的是,本地数据似乎会进入缓存,但永远不会回来。这是一个日志片段:</p>

<pre><code>History of :
=
=
=
=
=
=
=
=

=
=
=
=
</code></pre>

<p>我的期望是,在第一次被协议(protocol)拒绝后,它会导致几次缓存命中,但它总是将其视为未命中,从服务器获取内容,然后我开始获取缓存命中。 </p>

<p>我担心我的 <code>NSURLProtocol</code> 子类以一种允许它们被缓存的方式构造它的响应,但阻止它们被拉出缓存。有什么想法吗?</p>

<p>提前致谢。 :)</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>与 URL 加载系统的缓存交互是 <code>NSURLProtocolClient</code> 对象的职责,该对象充当 <code>NSURLProtocol</code> 的客户端。如果请求使用 <code>NSURLRequestUseProtocolCachePolicy</code> 作为缓存策略,则由协议(protocol)实现应用正确的特定于协议(protocol)的规则来确定是否应缓存响应。</p>

<p>协议(protocol)实现,在任何适合协议(protocol)的点,调用<a href="https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/Protocols/NSURLProtocolClient_Protocol/Reference/Reference.html#//apple_ref/doc/uid/20001701-GDIDAHIJ" rel="noreferrer noopener nofollow"><code>URLProtocol:cachedResponseIsValid:</code></a>在它的客户端上,表明缓存的响应是有效的。然后客户端应该与 URL 加载系统的缓存层进行交互。</p>

<p>但是,由于系统为我们提供的客户端是私有(private)且不透明的,您可能希望自己处理事务并与协议(protocol)中的系统缓存进行交互。如果你想走这条路,你可以直接使用 NSURLCache 。第一步是在你的协议(protocol)中覆盖 <code>-cachedResponse</code>。如果您仔细阅读文档,默认实现仅根据传递给初始化程序的值设置它。覆盖它以便它访问 <a href="https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/Classes/NSURLCache_Class/Reference/Reference.html#//apple_ref/doc/uid/20001699-SW4" rel="noreferrer noopener nofollow">shared URL cache</a> (或您自己的私有(private) URL 缓存):</p>

<pre><code>- (NSCachedURLResponse *) cachedResponse {
    return [ cachedResponseForRequest:];
}
</code></pre>

<p>现在,在您通常会在客户端调用 <code>cachedResponseIsValid:</code> 的地方,也将 <code>NSCachedURLResponse</code> 存储到 <code>NSURLCache</code> 中。例如,当您有完整的字节集和响应时:</p>

<pre><code>[ storeCachedResponse:cachedResponse forRequest:];
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何使用 NSURLCache 缓存由 NSURLProtocol 提供的内容,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/23374675/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/23374675/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何使用 NSURLCache 缓存由 NSURLProtocol 提供的内容