Alamofire 使用可配置缓存
Alamofire use configurable Caching
我正在使用 Alamofire 5 并要求缓存一些 GET 请求。如果数据早于 20 分钟,则真正的 API 应该被命中。
我发现的是使用 ResponseCacher。但是我没有看到配置个人请求的方法,需要一些建议。
let responseCacher = ResponseCacher(behavior: .modify { _, response in
let userInfo = ["date": Date()]
return CachedURLResponse(
response: response.response,
data: response.data,
userInfo: userInfo,
storagePolicy: .allowed)
})
let configuration = URLSessionConfiguration.af.default
private override init() {
configuration.timeoutIntervalForRequest = 10
configuration.requestCachePolicy = .reloadRevalidatingCacheData
Session(
configuration: configuration,
serverTrustManager: ServerTrustManager(evaluators: evaluators),
cachedResponseHandler: responseCacher
)
如果后端正在 return 进行适当的缓存 header,您希望将其限制在一定时间,在请求中添加 Cache-Control: max-age=
header可能有用。
如果后端没有 return 适当的缓存 header,使用 ResponseCacher
是可行的方法。您将修改 CachedURLResponse
的 response
以包含正确的 Cache-Control
header.
详细说明乔恩的回答,实现你想要的最简单的方法是让后端声明这个端点的缓存语义,然后确保在客户端, URLSession 使用 URLCache(这可能是默认的)并让 URLSession 和后端完成剩下的工作。 不过,这需要您控制后端!
更详细的答案:
这只是一个示例,服务器如何 return 具有声明的缓存语义的响应:
URL: https://www.example.com/ Status Code: 200
Age: 238645
Cache-Control: max-age=604800
Date: Tue, 12 Jan 2021 18:43:58 GMT
Etag: "3147526947"
Expires: Tue, 19 Jan 2021 18:43:58 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Vary: Accept-Encoding
x-cache: HIT
Accept-Ranges: bytes
Content-Encoding: gzip
Content-Length: 648
Content-Type: text/html; charset=UTF-8
Server: ECS (dcb/7EC7)
该服务器从字面上输出服务器可以声明的有关缓存的全部内容。前八 header 秒(从 Age
到 x-cache
)声明缓存。
例如,Cache-Control: max-age=604800
声明数据的 新鲜度 等于 604800 秒。有了服务器创建数据的日期,客户端现在可以检查数据是否仍然“新鲜”。
Expires: Tue, 19 Jan 2021 18:43:58 GMT
表示完全相同的意思,它声明 当 数据已过时指定挂钟。这与上面的声明是多余的,但是在 HTTP 中非常清楚地定义了客户端应该如何处理这个。
Age
header 是一个提示,表明响应实际上是从客户端和源服务器之间存在的缓存中传递的。 age
是此数据年龄的估计 - 从在源上创建到交付的持续时间。
我不想详细说明每个 header 的确切含义以及客户端和服务器应如何根据 HTTP 运行,因为这是一个非常激烈的话题,但是 你 基本上,当您定义端点时,只需 定义 returned 数据 .[=18= 的“新鲜度”的持续时间]
全部详情:Hypertext Transfer Protocol (HTTP/1.1): Caching
一旦你想出了一个好的持续时间,Web-application 框架(如 Rails、SpringBoot 等)在开箱即用地声明缓存语义方面提供了很大的帮助。然后 Web-application 框架将在响应中输出相应的 headers - 或多或少地“自动”。
URLSession 会根据 HTTP 协议自动做正确的事情(嗯,差不多)。也就是说,它会将响应存储在缓存中,当您执行后续请求时,它首先会在缓存中寻找合适的响应,并且 return 如果数据的“新鲜度”仍然存在,则该响应。
如果缓存的数据太旧(根据给定的响应 headers 和当前的数据和时间),它会尝试通过向源服务器发送请求来获取新的数据。任何上游缓存或最终的原始服务器可能会 return 新数据。您的 URLSession 数据任务会透明地完成所有这些工作,而不会让您知道数据是来自缓存还是来自原始服务器。老实说,在大多数情况下你不需要知道它。
根据 HTTP 声明缓存语义非常强大,通常应该适合您的需要。此外,客户端可以通过指定某些请求 header 来定制其需求,例如允许 return 甚至过时的数据或忽略任何缓存的值,等等。
每个细节都值得在 SO 上进行专门的问答。
我正在使用 Alamofire 5 并要求缓存一些 GET 请求。如果数据早于 20 分钟,则真正的 API 应该被命中。
我发现的是使用 ResponseCacher。但是我没有看到配置个人请求的方法,需要一些建议。
let responseCacher = ResponseCacher(behavior: .modify { _, response in
let userInfo = ["date": Date()]
return CachedURLResponse(
response: response.response,
data: response.data,
userInfo: userInfo,
storagePolicy: .allowed)
})
let configuration = URLSessionConfiguration.af.default
private override init() {
configuration.timeoutIntervalForRequest = 10
configuration.requestCachePolicy = .reloadRevalidatingCacheData
Session(
configuration: configuration,
serverTrustManager: ServerTrustManager(evaluators: evaluators),
cachedResponseHandler: responseCacher
)
如果后端正在 return 进行适当的缓存 header,您希望将其限制在一定时间,在请求中添加 Cache-Control: max-age=
header可能有用。
如果后端没有 return 适当的缓存 header,使用 ResponseCacher
是可行的方法。您将修改 CachedURLResponse
的 response
以包含正确的 Cache-Control
header.
详细说明乔恩的回答,实现你想要的最简单的方法是让后端声明这个端点的缓存语义,然后确保在客户端, URLSession 使用 URLCache(这可能是默认的)并让 URLSession 和后端完成剩下的工作。 不过,这需要您控制后端!
更详细的答案:
这只是一个示例,服务器如何 return 具有声明的缓存语义的响应:
URL: https://www.example.com/ Status Code: 200
Age: 238645
Cache-Control: max-age=604800
Date: Tue, 12 Jan 2021 18:43:58 GMT
Etag: "3147526947"
Expires: Tue, 19 Jan 2021 18:43:58 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Vary: Accept-Encoding
x-cache: HIT
Accept-Ranges: bytes
Content-Encoding: gzip
Content-Length: 648
Content-Type: text/html; charset=UTF-8
Server: ECS (dcb/7EC7)
该服务器从字面上输出服务器可以声明的有关缓存的全部内容。前八 header 秒(从 Age
到 x-cache
)声明缓存。
Cache-Control: max-age=604800
声明数据的 新鲜度 等于 604800 秒。有了服务器创建数据的日期,客户端现在可以检查数据是否仍然“新鲜”。
Expires: Tue, 19 Jan 2021 18:43:58 GMT
表示完全相同的意思,它声明 当 数据已过时指定挂钟。这与上面的声明是多余的,但是在 HTTP 中非常清楚地定义了客户端应该如何处理这个。
Age
header 是一个提示,表明响应实际上是从客户端和源服务器之间存在的缓存中传递的。 age
是此数据年龄的估计 - 从在源上创建到交付的持续时间。
我不想详细说明每个 header 的确切含义以及客户端和服务器应如何根据 HTTP 运行,因为这是一个非常激烈的话题,但是 你 基本上,当您定义端点时,只需 定义 returned 数据 .[=18= 的“新鲜度”的持续时间]
全部详情:Hypertext Transfer Protocol (HTTP/1.1): Caching
一旦你想出了一个好的持续时间,Web-application 框架(如 Rails、SpringBoot 等)在开箱即用地声明缓存语义方面提供了很大的帮助。然后 Web-application 框架将在响应中输出相应的 headers - 或多或少地“自动”。
URLSession 会根据 HTTP 协议自动做正确的事情(嗯,差不多)。也就是说,它会将响应存储在缓存中,当您执行后续请求时,它首先会在缓存中寻找合适的响应,并且 return 如果数据的“新鲜度”仍然存在,则该响应。
如果缓存的数据太旧(根据给定的响应 headers 和当前的数据和时间),它会尝试通过向源服务器发送请求来获取新的数据。任何上游缓存或最终的原始服务器可能会 return 新数据。您的 URLSession 数据任务会透明地完成所有这些工作,而不会让您知道数据是来自缓存还是来自原始服务器。老实说,在大多数情况下你不需要知道它。
根据 HTTP 声明缓存语义非常强大,通常应该适合您的需要。此外,客户端可以通过指定某些请求 header 来定制其需求,例如允许 return 甚至过时的数据或忽略任何缓存的值,等等。
每个细节都值得在 SO 上进行专门的问答。