Alamofire 4 Swift Cache Control -HTTP状态代码304(如果自修改后)



当我从服务器接收HTTP状态代码304时,服务器不会发送任何内容数据,因为没有任何更改。

现在,我想使用Alamofire 4的缓存控件(对于Swift 3)。但是我不知道它是如何工作的。我在这里找到了一些alamofire 3的示例

 Alamofire.request(req)
    .response {(request, res, data, error) in
        let cachedURLResponse = NSCachedURLResponse(response: res!, data: (data as NSData), userInfo: nil, storagePolicy: .Allowed)
        NSURLCache.sharedURLCache().storeCachedResponse(cachedURLResponse, forRequest: request)
    }

所以我认为该结构在Alamofire 4中会相似。但是我的内容保存在哪里?我希望我能做这样的事情

伪代码:

if response.statusCode == 304 {
   return cacheControl.response
}

有人有想法吗?有疑问,我自己写了它。

我设法恢复了旧的缓存内容,以防状态代码为304:

let sessionManager: SessionManager = {
    let configuration = URLSessionConfiguration.default
    configuration.requestCachePolicy = .reloadIgnoringCacheData
    configuration.timeoutIntervalForRequest = 60
    let memoryCapacity = 500 * 1024 * 1024; // 500 MB
    let diskCapacity = 500 * 1024 * 1024; // 500 MB
    let cache = URLCache(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: "shared_cache")
     configuration.urlCache = cache
    return SessionManager(configuration: configuration)
}()

func getData(url:URLConvertible,completionHadler:@escaping(Data?,ErrorMessage?)->Void){
    let headers: HTTPHeaders =
    [   "Authorization":token!,
    "Accept": "application/json",
    "if-None-Match":  self.loadEtagUserDefault(keyValue: "Etag")
  ]
  
  
  self.sessionManager.request(url, method: .get, parameters:nil, headers: headers)
  
  .validate()
  
  .responseJSON { (response) in
    
    switch (response.result) {
    case .success:
      
      // SAVE THE RESPONSE INSIDE THE CACHE
      
      self.saveCache(response)
      
      //---
      
      if let unwrappedResponse = response.response {
        _ = unwrappedResponse.statusCode
      }
      // If all went well, I'll return the date
         // Recovery Etag from the Header
      let etag =  response.response?.allHeaderFields["Etag"] as? String
      //update in memoria Etag
      self.saveEtagUserDefault(etagValue: etag!, key: "Etag")
      
      print("stato codice: (String(describing: response.response?.statusCode))")
      completionHadler(response.data,nil)
      
      break
    case .failure(let error):
      print(error.localizedDescription)
      let statusCode = response.response?.statusCode
      let url1:URLRequest? = try! response.request?.asURLRequest()
      
      //Nel caso lo status code è nil perciò il sito non e raggiungibile restituisce la vecchia cache
      guard let _ = statusCode else {
        
        let dataOld = self.loadOldDataCache(url: url1!)
        completionHadler(dataOld,nil)
        
        return
      }
    // If the status code is 304 (no change) I return the old cache
      if statusCode == 304 {
        
        print("beccato codice 304 ***")
        let dataOld = self.loadOldDataCache(url: url1!)
        guard let _ = dataOld else {
          completionHadler(nil,ErrorMessage.error(description: "data nil"))
          return
        }
        completionHadler(dataOld,nil)
        return
      }
      
      
    // *** IN CASE OF ERROR 401 refresh the token and recursively call the same method
      print("error - > n    (error.localizedDescription) n")
      
      print("stato codice2: (String(describing: statusCode))")
      
    
    }
  
  
}
}

//Save the response in the cache
private func saveCache(_ response: (DataResponse<Any>)) {
  let cachedResponse = CachedURLResponse(response: response.response!, data: response.data!, userInfo: nil, storagePolicy: .allowed)
  let mycache:URLCache = self.sessionManager.session.configuration.urlCache!
  mycache.storeCachedResponse(cachedResponse, for: response.request!)
}

// Given a Request URL returns the old CACHE in case the site is unresponsive or offline
private func loadOldDataCache(url:URLRequest)->Data?{
  let myCache:URLCache = self.sessionManager.session.configuration.urlCache!
  let cacheResponse = myCache.cachedResponse(for: url)
  return cacheResponse?.data
}
// Except in memory Etag
private func saveEtagUserDefault(etagValue:String,key:String)->Void{
  
  UserDefaults.standard.set(etagValue, forKey:key)
  UserDefaults.standard.synchronize()
  
}
// Recovery from the memory Etag
private func loadEtagUserDefault(keyValue:String)->String{
  return UserDefaults.standard.object(forKey: keyValue) as? String ?? "0"
}
}

迭戈在评论中问我如何解决这个问题。不幸的是,我无法以正确的方式解决它。

我所做的是为Alamofire创建了自己的网络管理器。

    class NetworkManager {
     static let sharedInstance: SessionManager = {
        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
        configuration.timeoutIntervalForRequest = 20.0
        configuration.timeoutIntervalForResource = 20.0
        configuration.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
        configuration.urlCache = nil
        return SessionManager(configuration: configuration)
      }()
   }

重要行是configuration.urlCache = nil。因此,Alamofire不会缓存任何东西。我当然知道这不是正确的方法,但是ATM这是我用例的O-KAY的解决方案。

您像这样称呼此经理

    NetworkManager.sharedInstance.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: contentAuthorization).responseJSON { (response) in
        switch(response.result) {
        case .success(_):
            //success
        case .failure(let errorValue):
            print(errorValue)
        }
    }

最新更新