原文:http://www.shinobicontrols.com/b
... day-1-nsurlsession/
大家都知道,过去的IOS系统网络处理是通过NSURLConnection来实现的。由于NSURLConnection通过全局状态来管理cookies和认证信息,这就意味着在某种情况下,可能同时存在两个不同的连接去使用这些公共资源。NSURLSession很好的解决了许多这种类似的问题。
本文连同附件一共讨论了三种不同的下载场景。本文会着重讲述有关NSURLSession的部分,整个项目就不再阐述了。代码可以在github回购。
NSURLSession状态同时对应着多个连接,不像之前使用共享的一个全局状态。会话是通过工厂方法来创建配置对象。
总共有三种会话:
1. 默认的,进程内会话
2. 短暂的(内存),进程内会话
3. 后台会话
如果是简单的下载,我们只需要使用默认模式即可:
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
配置对象有很多属性。例如,可以设置TLS安全等级,TLS决定你可以使用cookies和超时时间。还有两个非常有趣的属性:allowsCellularAccess和discretionary。前一个属性表示当只有一个3G网络时,网络是否允许访问。设置discretionary属性可以控制系统在一个合适的时机访问网络,比如有可用的WiFi,有充足的电量。这个属性主要针对后台回话的,所以在后台会话模式下默认是打开的。
当我们创建了一个会话配置对象后,就可以用它来创建会话对象了:
1 |
NSURLSession
*inProcessSession; |
2 |
inProcessSession
= [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil]; |
注意:这里我们把自己设置为代理了。通过代理方法可以告诉我们数据传输进度以及获取认证信息。下面我们会实现一些合适的代理。
数据传输时封装在任务里面的,这里有三种类型:
1. 数据任务 (NSURLSessionDataTask)
2. 上传任务 (NSURLSessionUploadTask)
3. 下载任务(NSURLSessionDownloadTask)
在会话中传输数据时,我们需要实现某一种任务。比如下载:
2 |
NSURLRequest
*request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]]; NSURLSessionDownloadTask *cancellableTask = [inProcessSession downloadTaskWithRequest:request]; |
3 |
[cancellableTask
resume]; |
现在会话将会异步下载此url的文件内容。
我们需要实现一个代理方法来获取这个下载的内容:
01 |
-
( void )URLSession:(NSURLSession
*)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location |
04 |
-
NSFileManager *fileManager = [NSFileManager defaultManager]; |
05 |
-
NSArray *URLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]; |
06 |
-
NSURL *documentsDirectory = URLs[0]; |