当我从服务器接收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)
}
}