如何在 Alamofire 中禁用缓存

Posted

技术标签:

【中文标题】如何在 Alamofire 中禁用缓存【英文标题】:How to disable caching in Alamofire 【发布时间】:2015-08-25 08:47:29 【问题描述】:

当我使用 Alamofire 两次发送 GET 请求时,我得到了相同的响应,但我期待的是不同的响应。我想知道这是否是因为缓存,如果是,我想知道如何禁用它。

【问题讨论】:

对我来说,以下解决方案或我发现的任何解决方案都不起作用。结果发现,我的托管服务提供商进行了一些更改,并且 JSON 文件“卡住”了,尽管我会对其进行编辑,但它始终显示相同的文件。使用另一台主机,它工作。可能很少有人会遇到同样的问题,但值得注意。 【参考方案1】:

你有几个选择。

完全禁用 URLCache

let manager: Manager = 
    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    configuration.URLCache = nil
    return Manager(configuration: configuration)
()

配置请求缓存策略

let manager: Manager = 
    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    configuration.requestCachePolicy = .ReloadIgnoringLocalCacheData
    return Manager(configuration: configuration)
()

这两种方法都应该为您解决问题。有关更多信息,我建议阅读NSURLSessionConfiguration 和NSURLCache 的文档。另一个很好的参考是 NSHipster 在NSURLCache 上的文章。

【讨论】:

这段代码应该放在哪里?在应用程序委托?请详细说明。 @user3246173 见Alamofire#manager 对我不起作用。而且在阅读了附加链接中的所有内容后,我仍然不知道在哪里调用此代码。 在某个时候,“Manager”变成了“SessionManager”,其他一些事情也发生了变化。 Swift 3 版本:let manager: SessionManager = let configuration = URLSessionConfiguration.default configuration.requestCachePolicy = .reloadIgnoringLocalCacheData return SessionManager(configuration: configuration) ()【参考方案2】:

这对我有用。

NSURLCache.sharedURLCache().removeAllCachedResponses()

斯威夫特 3

URLCache.shared.removeAllCachedResponses()

【讨论】:

我可以确认这是可行的。每次在我进行网络调用之前调用上述代码。 @Andrej 而不是我刚刚在 AppDelegate 中调用它didFinishLaunchWithOptions【参考方案3】:

swift 3,alamofire 4

我的解决方案是:

为 Alamofire 创建扩展:

extension Alamofire.SessionManager
    @discardableResult
    open func requestWithoutCache(
        _ url: URLConvertible,
        method: HTTPMethod = .get,
        parameters: Parameters? = nil,
        encoding: ParameterEncoding = URLEncoding.default,
        headers: HTTPHeaders? = nil)// also you can add URLRequest.CachePolicy here as parameter
        -> DataRequest
    
        do 
            var urlRequest = try URLRequest(url: url, method: method, headers: headers)
            urlRequest.cachePolicy = .reloadIgnoringCacheData // <<== Cache disabled
            let encodedURLRequest = try encoding.encode(urlRequest, with: parameters)
            return request(encodedURLRequest)
         catch 
            // TODO: find a better way to handle error
            print(error)
            return request(URLRequest(url: URL(string: "http://example.com/wrong_request")!))
        
    

并使用它:

Alamofire.SessionManager.default
            .requestWithoutCache("https://google.com/").response  response in
                print("Request: \(response.request)")
                print("Response: \(response.response)")
                print("Error: \(response.error)")
        

【讨论】:

同意!谢谢你。我也做了一个 requestWithCache 函数,现在我只使用正确的函数。我认为这应该默认包含在 Alamofire 中 像魅力一样工作! 这似乎对我不起作用。您确定这会阻止从缓存中读取,而不仅仅是阻止写入缓存吗?因此,如果缓存中仍有某些内容,您无论如何都会得到它?我在使用 iTunes 查找来检查是否有新的应用程序版本时遇到缓存问题:https://itunes.apple.com/nl/lookup/?id=1234567890。使用 removeAllCachedResponses() 清除缓存确实有效。 您能帮我如何使用 Alamofire 启用长达 3 分钟的缓存吗? 缓存生命周期可以在服务器端的 Cache-Control 中设置:max-age=。要了解如何使用 Alamofire 做同样的事情,请在 *** 上创建另一个问题。【参考方案4】:
func getImage(url: String, completion: @escaping (UIImage?) -> ()) 

    let urlRequest = URLRequest(url: URL(string: url)!)
    URLCache.shared.removeCachedResponse(for: urlRequest)
    //URLCache.shared.removeAllCachedResponses()

    Alamofire.request(url).responseData  (dataResponse) in
        guard let data = dataResponse.data else 
            return completion(nil)
        
        completion(UIImage(data: data, scale:1))
    

【讨论】:

【参考方案5】:

Alamofire 4Swift 3 中:

// outside function, inside class
var sessionManager: SessionManager!

func someFunc() 
    let configuration = URLSessionConfiguration.default
    configuration.urlCache = nil
    let sessionManager = Alamofire.SessionManager(configuration: configuration)
    sessionManager.request("http://example.com/get").responseJSON  response in
        // ...
    

【讨论】:

以上评论:github.com/Alamofire/Alamofire/issues/157 与***.com/a/32230328/5790492 相同,更新答案比复制更好。【参考方案6】:

[此方法不会禁用缓存,它只是确保 缓存的文件不会被重用]

解决特定调用的缓存问题的更简单方法是在调用参数中添加一个随机数。

对于 Swift 3,您可以使用 arc4random() 生成随机数。

【讨论】:

是的,这不是停止呼叫缓存的好方法,而是避免特定呼叫缓存数据的快速方法。对测试很有用,显然不是摆脱缓存的解决方案,因为每个带有随机数的调用仍然会被缓存。【参考方案7】:

您可以尝试将缓存控制添加到您的标题中。

let headers = ["Authorization": "Bearer \(token)",
               "Cache-Control": "no-cache"]

【讨论】:

【参考方案8】:

我自己解决了

configuration.urlCache?.removeAllCachedResponses()

【讨论】:

【参考方案9】:

在再次触发该请求之前删除缓存的响应会更合适,例如:

let url = "http://google.com"
let urlRequest = URLRequest(url: URL(string: url)!)

URLCache.shared.removeCachedResponse(for: urlRequest)

Alamofire
  .request(urlRequest)
  .responseJSON(completionHandler:  response in
    //handle response

【讨论】:

你的情况怎么样? urlRequest.cachePolicy = .reloadIgnoringCacheData 工作

以上是关于如何在 Alamofire 中禁用缓存的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Alamofire 中禁用缓存(Xcode 9 - swift 4)

错误:导入 Alamofire

在 Alamofire 4.0 中初始化 SessionManager

为啥我无法从 Alamofire 获取请求结果

Alamofire 请求大约需要 10 秒

强制 Alamofire 在主线程上做所有事情?