Swift - 二次封装AFN(无网络走缓存基本原理)
2017-10-28 本文已影响63人
iOS苏帕君
Q:AFN网络框架怎么会跟缓存有一腿呢?缓存不是FMDB的事吗?两脸愣比
A: 了解URL缓存机制
0.1 AFNetworking使用NSURLConnection,它利用了原生的缓存机制NSURLCache
0.2 NSURLCache缓存了从服务器返回的NSURLResponse对象
0.3 NSURLCache的默认配置只是缓存在内存并没有写到硬盘
import YYCache
// YYCache配合缓存用
1.1 从内存中读,有就直接拿来用
1.2 没有再从磁盘读,有就拿来用,并写入内存中
1.3 仍然没有就返回空
import AFNetworking // CocoaSecurity将字符串转换为MD5工具 import CocoaSecurity enum AFNRequestMethod { case GET case POST } class NetworkTools: AFHTTPSessionManager { /** * @param method 请求方式 * @param parameters 请求参数 * @param finished 完成回调 */ func request(method:AFNRequestMethod,URLString:String,parameters:[Any],finished:@escaping (_ data:Any?,_ error:Error?)->()){ //2.1发起网络请求时进来通过URL到磁盘查找是否存在已缓存有的 if let responseByCache = NetworkTools.cacheJsonWithURL(URLString: URLString) { finished(responseByCache, nil) return } //成功回调 let success_block:((URLSessionDataTask, Any?) -> Swift.Void) = { (task, anyValue)->Void in finished(anyValue, nil) // 2.2 调用保存请求响应文件 NetworkTools.saveResponseToCacheFile(jsonResponse: anyValue, andURL: URLString) } //失败回调 let failure_block:((URLSessionDataTask?, Error) -> Swift.Void) = { (task,err)->Void in finished(nil, err) } if method == AFNRequestMethod.GET{ get(URLString, parameters: parameters, progress: nil, success: success_block, failure: failure_block) } else if method == AFNRequestMethod.POST{ post(URLString, parameters: parameters, progress: nil, success: success_block, failure: failure_block) } } extension NetworkTools{ // 查找是否存在缓存处理 class func cacheJsonWithURL(URLString:String) ->(Any?){ // path_md5 通过CocoaSecurity用URL字符串返回MD5 let path_md5:String = self.returnCompletionPathByMd5(URLString: URLString) // 创建YYCache会在path_md5沙盒路径下自动创建文件夹 let cache = YYCache.init(path: path_md5) let isContains = cache?.containsObject(forKey: URLString) ?? false if isContains { return cache?.object(forKey:URLString) } return nil } //保存过程处理 class func saveResponseToCacheFile(jsonResponse:Any?,andURL URLString:String){ let path = self.returnCompletionPathByMd5(URLString: URLString) let cache = YYCache.init(path: path) guard jsonResponse != nil else { return } let isExist:Bool = cache?.containsObject(forKey: URLString) ?? false cache?.setObject(jsonResponse as! NSCoding, forKey: URLString) if isExist { print("保存[\(URLString)]成功") } } }