iOS 原生网络请求快速回顾

1,729 阅读4分钟

URL Loading System

在了解Alamofire,AFNetworking之前,需要复习原生网络是怎么使用的。

主要分为三大块, URLSessionConfigurationURLSessionURLSessionTask

URLSessionConfiguration

URLSessionConfigurationURLSession初始化时,必须传入的参数,设定如何去使用caches,cookies等缓存策略,或者超时时间的设定,或者是否允许在非wifi的移动网上使用等等。 在创建时,主要分为三类。

  1. Default。默认设定。
  2. ephemeral。不对caches, cookies, or credentials使用存储。
  3. 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()

URLSesion

如果指定了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)
}

URLSesion

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请求,以查看资源是否已更改。如果修改了,将从原始源获取数据,如果不是,则返回缓存内容。

URLSesion