gpt4 book ai didi

ios - 如何使用 NSURLSession 来判断资源是否发生了变化?

转载 作者:行者123 更新时间:2023-12-01 17:25:04 34 4
gpt4 key购买 nike

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

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

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

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

最佳答案

我创建了一个 HTTPEntityFingerprint 结构来存储一些实体 header :Content-MD5EtagLast-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 响应并保存新指纹。

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

更多关于 NSURLSession 和 NSURLCache 行为的细节

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

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

关于ios - 如何使用 NSURLSession 来判断资源是否发生了变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31551964/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com