Alamofire 使用可配置缓存 [英] Alamofire use configurable Caching

查看:58
本文介绍了Alamofire 使用可配置缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Alamofire 5 并且要求缓存一些 GET 请求.如果数据早于 20 分钟,则应命中真正的 API.

I'm using Alamofire 5 and have the requirement that some GET-requests should be cached. If the data is older then 20 minutes the real API should be hit.

我发现的是使用 ResponseCacher.但是我看不到配置单个请求的方法,需要一些建议.

What I found is to use the ResponseCacher. But I do not see a way to configure the individual request and need some advice.

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
   )

推荐答案

为了详细说明 Jon 的答案,实现你想要的最简单的方法就是让后端声明这个缓存语义端点,然后确保在客户端,URLSession 使用 URLCache(无论如何这可能是默认值)并让 URLSession 和后端完成其余的工作.这要求您可以控制后端!

To elaborate on Jon's answer, the easiest way to achieve what you want is to just let the backend declare the cache semantics of this endpoint, then ensure that on the client side, URLSession uses a URLCache (which is probably the default anyway) and let URLSession and the backend do the rest. This requires, that you have control over the backend, though!

更详细的答案:

这里只是一个例子,服务器如何使用声明的缓存语义返回响应:

Here is just an example, how a server may return a response with declared cache semantics:

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)

这个服务器从字面上输出服务器可以声明的关于缓存的全部范围.前八个标头(从 Agex-cache)声明缓存.

This server literally outputs the full range of what a server can declare regarding caching. The first eight headers (from Age to x-cache) declare the caching.

Cache-Control: max-age=604800 例如声明,数据的新鲜度等于 604800 秒.有了服务器创建数据的日期,客户端现在可以检查数据是否仍然新鲜".

Cache-Control: max-age=604800 for example declares, that the data's freshness equals 604800 seconds. Having the date when the server created the data, the client can now check if the data is still "fresh".

Expires: Tue, 19 Jan 2021 18:43:58 GMT 意思完全一样,它声明 when 指定挂钟的数据已过时.这与上面的声明是多余的,但是在 HTTP 中非常清楚地定义了客户端应该如何处理.

Expires: Tue, 19 Jan 2021 18:43:58 GMT means the exact same thing, it declares when the data is outdated specifying the wall clock. This is redundant with the above declaration, but it is very clearly defined in the HTTP how clients should treat this.

具有 Age 标头是一个提示,表明响应实际上是从客户端和源服务器之间存在的缓存中传送的.age 是对该数据年龄的估计 - 从它在源上创建到交付的持续时间.

Having an Age header is a hint, that the response has been actually delivered from a cache that exists between the client and the origin server. The age is the estimation of this data's age - the duration from when it has been created on the origin and when it has been delivered.

我不会详细介绍每个标头的确切含义以及客户端和服务器应如何根据 HTTP 进行操作,因为这是一个非常激烈的话题,但是基本上要做的是当你定义一个端点时,只是为了定义新鲜度"的持续时间;返回的数据.

I don't wont to go into detail what every header means exactly and how a client and server should behave according HTTP since this is a very intense topic, but what you have to do is basically when you define an endpoint, is just to define the duration of the "freshness" of the returned data.

全部细节:超文本传输​​协议 (HTTP/1.1):缓存

一旦你想出了一个好的持续时间,Web 应用程序框架(如 Rails、SpringBoot 等)在声明开箱即用的缓存语义方面提供了很大的帮助.然后 Web 应用程序框架将在响应中输出相应的标头 - 或多或少自动".

Once you came up with a good duration, Web-application frameworks (like Rails, SpringBoot, etc.) give great help with declaring cache semantics out of the box. Then Web-application frameworks will output the corresponding headers in the response - more or less "automagically".

URLSession 会根据 HTTP 协议自动做正确的事情(好吧,差不多).也就是说,它将响应存储在缓存中,当您执行后续请求时,它首先在缓存中查找合适的响应,如果新鲜度"低于该响应,则返回该响应.的数据仍然给出.

The URLSession will automatically do the right thing according the HTTP protocol (well, almost). That is, it will store the response in the cache and when you perform a subsequent request it first looks for a suitable response in the cache and return that response if the "freshness" of the data is still given.

如果缓存的数据太旧(根据给定的响应头和当前数据和时间),它将尝试通过向源服务器发送请求来获取新数据.任何上游缓存或最终源服务器可能会返回新数据.您的 URLSession 数据任务会透明地完成所有这些工作,而不会为您提供数据来自缓存还是源服务器的线索.老实说,在大多数情况下,您不需要知道它.

If that cached data is too old (according the given response headers and the current data and time), it will try to get a fresh data by sending the request to the origin server. Any upstream cache or eventually the origin server may then return fresh data. Your URLSession data task does all this transparently without giving you a clue whether the data comes from the cache or the origin server. And honestly, in most cases you don't need to know it.

根据 HTTP 声明缓存语义非常强大,它通常应该适合您的需求.此外,客户端可以通过指定某些请求标头来定制其需求,例如允许返回甚至过时的数据或忽略任何缓存值等等.

Declaring the cache semantics according HTTP is very powerful and it usually should suit your needs. Also, the client may tailor its needs with specifying certain request headers, for example allowing to return even outdated data or ignoring any cached values, and much more.

每个细节都值得专门针对 SO 进行问答.

Every detail may deserve a dedicated question and answer on SO.

这篇关于Alamofire 使用可配置缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆