1. <small id='b35gx'></small><noframes id='b35gx'>

    2. <legend id='b35gx'><style id='b35gx'><dir id='b35gx'><q id='b35gx'></q></dir></style></legend>
      <i id='b35gx'><tr id='b35gx'><dt id='b35gx'><q id='b35gx'><span id='b35gx'><b id='b35gx'><form id='b35gx'><ins id='b35gx'></ins><ul id='b35gx'></ul><sub id='b35gx'></sub></form><legend id='b35gx'></legend><bdo id='b35gx'><pre id='b35gx'><center id='b35gx'></center></pre></bdo></b><th id='b35gx'></th></span></q></dt></tr></i><div id='b35gx'><tfoot id='b35gx'></tfoot><dl id='b35gx'><fieldset id='b35gx'></fieldset></dl></div>
        <tfoot id='b35gx'></tfoot>

        • <bdo id='b35gx'></bdo><ul id='b35gx'></ul>
      1. 如何使用 NSURLSession 来判断资源是否发生了变化?

        时间:2023-06-11

          <small id='a97S2'></small><noframes id='a97S2'>

            • <bdo id='a97S2'></bdo><ul id='a97S2'></ul>

                  <tbody id='a97S2'></tbody>
              1. <tfoot id='a97S2'></tfoot>
                <i id='a97S2'><tr id='a97S2'><dt id='a97S2'><q id='a97S2'><span id='a97S2'><b id='a97S2'><form id='a97S2'><ins id='a97S2'></ins><ul id='a97S2'></ul><sub id='a97S2'></sub></form><legend id='a97S2'></legend><bdo id='a97S2'><pre id='a97S2'><center id='a97S2'></center></pre></bdo></b><th id='a97S2'></th></span></q></dt></tr></i><div id='a97S2'><tfoot id='a97S2'></tfoot><dl id='a97S2'><fieldset id='a97S2'></fieldset></dl></div>
                • <legend id='a97S2'><style id='a97S2'><dir id='a97S2'><q id='a97S2'></q></dir></style></legend>
                  本文介绍了如何使用 NSURLSession 来判断资源是否发生了变化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在使用 NSURLSession 从 HTTP 服务器请求 JSON 资源.服务器使用 Cache-Control 来限制资源在客户端缓存的时间.

                  I'm using NSURLSession to request a JSON resource from an HTTP server. The server uses Cache-Control to limit the time the resource is cached on clients.

                  这很好用,但我还想在内存中缓存一个反序列化的 JSON 对象,因为它经常被访问,同时继续利用 NSURLSession 中内置的 HTTP 缓存机制.

                  This works great, but I'd also like to cache a deserialized JSON object in memory as it is accessed quite often, while continuing to leverage the HTTP caching mechanisms built into NSURLSession.

                  我想我可以保存一些 HTTP 响应标头:Content-MD5EtagLast-Modified 以及反序列化的 JSON 对象(我正在使用这 3 个字段,因为我注意到并非所有 HTTP 服务器都返回 Content-MD5,否则这本身就足够了).下次我收到 JSON 对象的响应时,如果这 3 个字段相同,那么我可以重用之前反序列化的 JSON 对象.

                  I'm thinking I can save a few HTTP response headers: Content-MD5, Etag, and Last-Modified along with the deserialized JSON object (I'm using those 3 fields since I've noticed not all HTTP servers return Content-MD5, otherwise that'd be sufficient by itself). The next time I receive a response for the JSON object, if those 3 fields are the same then I can reuse the previously deserialized JSON object.

                  这是确定反序列化 JSON 是否仍然有效的可靠方法.如果不是,如何确定反序列化的对象是否是最新的?

                  Is this a robust way to determine the deserizlied JSON is still valid. If not, how do I determine if the deserialized object is up to date?

                  推荐答案

                  我创建了一个 HTTPEntityFingerprint 结构来存储一些实体标头:Content-MD5EtagLast-Modified.

                  I created a HTTPEntityFingerprint structure which stores some of the entity headers: Content-MD5, Etag, and Last-Modified.

                  import Foundation
                  
                  struct HTTPEntityFingerprint {
                      let contentMD5 : String?
                      let etag : String?
                      let lastModified : String?
                  }
                  
                  extension HTTPEntityFingerprint {
                      init?(response : NSURLResponse) {
                          if let httpResponse = response as? NSHTTPURLResponse {
                              let h = httpResponse.allHeaderFields
                              contentMD5 = h["Content-MD5"] as? String
                              etag = h["Etag"] as? String
                              lastModified = h["Last-Modified"] as? String
                  
                              if contentMD5 == nil && etag == nil && lastModified == nil {
                                  return nil
                              }
                          } else {
                              return nil
                          }
                      }
                  
                      static func match(first : HTTPEntityFingerprint?, second : HTTPEntityFingerprint?) -> Bool {
                          if let a = first, b = second {
                              if let md5A = a.contentMD5, md5B = b.contentMD5 {
                                  return md5A == md5B
                              }
                              if let etagA = a.etag, etagB = b.etag {
                                  return etagA == etagB
                              }
                              if let lastA = a.lastModified, lastB = b.lastModified {
                                  return lastA == lastB
                              }
                          }
                  
                          return false
                      }
                  }
                  

                  当我从 NSURLSession 获得 NSHTTPURLResponse 时,我会从中创建一个 HTTPEntityFingerprint 并使用 将其与之前存储的指纹进行比较>HTTPEntityFingerprint.match.如果指纹匹配,那么 HTTP 资源没有改变,因此我不需要再次反序列化 JSON 响应;但是,如果指纹不匹配,我会反序列化 JSON 响应并保存新指纹.

                  When I get an NSHTTPURLResponse from an NSURLSession, I create an HTTPEntityFingerprint from it and compare it against a previously stored fingerprint using HTTPEntityFingerprint.match. If the fingerprints match, then the HTTP resource hasn't changed and thus I do not need to deserialized the JSON response again; however, if the fingerprints do not match, then I deserialize the JSON response and save the new fingerprint.

                  此机制仅在您的服务器至少返回以下 3 个实体标头之一时才有效:Content-MD5EtagLast-Modified.

                  This mechanism only works if your server returns at least one of the 3 entity headers: Content-MD5, Etag, or Last-Modified.

                  NSURLSession 通过 NSURLCache 提供的缓存是透明的,这意味着当您请求以前缓存的资源时,NSURLSession 将调用完成处理程序/委托好像发生了 200 响应.

                  The caching provided by NSURLSession via NSURLCache is transparent, meaning when you request a previously cached resource NSURLSession will call the completion handlers/delegates as if a 200 response occurred.

                  如果缓存的响应已经过期,那么 NSURLSession 会向源服务器发送一个新的请求,但是会包含 If-Modified-SinceIf-None-Match在缓存(尽管已过期)结果中使用 Last-ModifiedEtag 实体标头的标头;此行为是内置的,除了启用缓存之外,您无需执行任何操作.如果源服务器返回 304(未修改),则 NSURLSession 会将其转换为应用程序的 200 响应(使其看起来像您获取了资源的新副本,即使它仍然被提供从缓存中).

                  If the cached response has expired then NSURLSession will send a new request to the origin server, but will include the If-Modified-Since and If-None-Match headers using the Last-Modified and Etag entity headers in the cached (though expired) result; this behavior is built in, you don't have to do anything besides enable caching. If the origin server returns a 304 (Not Modified), then NSURLSession will transform this to a 200 response the application (making it look like you fetched a new copy of the resource, even though it was still served from the cache).

                  这篇关于如何使用 NSURLSession 来判断资源是否发生了变化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:应该使用什么标头将 GZIP 压缩 JSON 从 Android 客户端发送到服务器? 下一篇:iPhone 应用中的全局 ADBannerView

                  相关文章

                      <bdo id='Jr47n'></bdo><ul id='Jr47n'></ul>
                    <tfoot id='Jr47n'></tfoot>

                    <small id='Jr47n'></small><noframes id='Jr47n'>

                  1. <i id='Jr47n'><tr id='Jr47n'><dt id='Jr47n'><q id='Jr47n'><span id='Jr47n'><b id='Jr47n'><form id='Jr47n'><ins id='Jr47n'></ins><ul id='Jr47n'></ul><sub id='Jr47n'></sub></form><legend id='Jr47n'></legend><bdo id='Jr47n'><pre id='Jr47n'><center id='Jr47n'></center></pre></bdo></b><th id='Jr47n'></th></span></q></dt></tr></i><div id='Jr47n'><tfoot id='Jr47n'></tfoot><dl id='Jr47n'><fieldset id='Jr47n'></fieldset></dl></div>

                    1. <legend id='Jr47n'><style id='Jr47n'><dir id='Jr47n'><q id='Jr47n'></q></dir></style></legend>