URL Loading System
在了解Alamofire,AFNetworking之前,需要复习原生网络是怎么使用的。
主要分为三大块, URLSessionConfiguration、 URLSession、URLSessionTask。
URLSessionConfiguration
URLSessionConfiguration是URLSession初始化时,必须传入的参数,设定如何去使用caches,cookies等缓存策略,或者超时时间的设定,或者是否允许在非wifi的移动网上使用等等。
在创建时,主要分为三类。
- Default。默认设定。
- ephemeral。不对caches, cookies, or credentials使用存储。
- backgroud。允许上传下载等操作可以在后台执行。
在使用URLSessionConfiguration创建URLSession需要注意:
在初始化之前,需要对Config进行充足的设定,在创建后Session会拷贝一份保存,所以这时候再对Config进行修改,则不会影响Session。如果这时候需要修改一些Config的内容,就只能通过更新Config后再重新创建Session。
在大部分情况下,NSURLRequest能够override Configruation中的内容,比如超时时间的设定,但对于某些严格的参数,比如allowsCellularAccess,则不能覆盖。
URLSession
通过设定URLSessionConfiguration之后,就可以创建URLSession,URLSession的主要功能就是创建一个或者多个 URLSessionTask的实例。
在创建时,可以指定URLSessionDelegate 以及 delegateQueue,如果不需要delegate,直接传入nil即可。
init(configuration: URLSessionConfiguration, delegate: URLSessionDelegate?, delegateQueue queue: OperationQueue?)
URLSessionDelegate的继承关系: URLSessionDelegate -> URLSessionTaskDelegate -> [URLSessionDataDelegate, URLSessionDownloadDelegate, URLSessionStreamDelegate, URLSessionWebSocketDelegate]
需要注意的是,这里的Degelate是会被Session以强引用的方式持有,如果没有对Session调用invalidateAndCancel() 或者finishTasksAndInvalidate(),那么生命周期会知道app关闭,造成内存泄漏。
这里的queue是指代调用Delegate中方法或者是completion handlers使用的队列。为了保证正确的顺序,该线程必须是串行队列,如果没有指定,session也会自动创建。
如果不指定delegate, 在穿件task之后则执行传入的闭包:
let task = URLSession.shared.dataTask(with: url) { data, response, error in
dosomething()
}
task.resume()

如果指定了delegate,则不必再传入handler,如果传入,则不会走delegate的回调。
private lazy var session: URLSession = {
let configuration = URLSessionConfiguration.default
configuration.waitsForConnectivity = true
return URLSession(configuration: configuration,
delegate: self, delegateQueue: nil)
}()
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
self.receivedData?.append(data)
}

URLSessionTask
URLSessionTask,由URLSession生成,主要分为四种:
URLSessionDataTask:一般请求资源,返回服务器的response,作为NSData对象缓存在内存中。不支持background session生成。
URLSessionUploadTask: 与URLSessionDataTask类似,但是请求中添加request body更加容易。
URLSessionDownloadTask: 支持直接在磁盘中下载文件。
URLSessionStreamTask:流任务从主机名和端口或网络服务对象建立TCP / IP连接。。
在创建Task之后,如果调用了resume,session会自动将其设为强引用,直到请求结束或者失败,所以开发者没必要去维持一个引用。
除了resume,还有cancel,suspend等方法进行操作。
缓存系统
URLCache
在网络请求中,会在内存或者磁盘中缓存response,以此提高性能以及减少网络交互。
缓存数据的类叫做URLCache,缓存从NSURLRequest映射为CachedURLResponse的对象。
在磁盘上的缓存也会当磁盘空间低的时候被系统移除,也只会在app未开启的情况下。
如果想自定义URLCache,比如缓存大小,需要在URLSessionConfiguration中设定。
Cache Policy
对于每一个URLRequest的实例,都有缓存属性cachePolicy。
为了方便统一管理,可以直接对URLSessionConfiguration的requestCachePolicy属性进行设置,这样每一个使用Config的Session生成请求的cachePolicy都会继承。
缓存策略分为4种:
- reloadIgnoringLocalCacheData: 忽略本地缓存,直接从远端获取资源。
- returnCacheDataDontLoad:只从缓存中获取,不会对远端发起请求,如果没有缓存则会进入fail,一般用与离线模式。
- returnCacheDataElseLoad: 从缓存中获取,如果没有缓存则对远端发起请求。
- useProtocolCachePolicy:默认策略。
如果没有缓存,则发起请求; 如果缓存的响应不需要每次都重新验证,并且缓存的响应没有过期,则返回缓存。如果缓存过期或需要重新验证,则向原始源发出HEAD请求,以查看资源是否已更改。如果修改了,将从原始源获取数据,如果不是,则返回缓存内容。
