这篇博客分为五个部分,前面四个部分是对NSURLSession的总结;最后一个部分通过一个音乐播放器的Demo来进行实际操练。这个音乐播放器有以下功能:查询歌曲--下载歌曲--保存并播放歌曲--查看下载过程--继续暂停取消下载歌曲。
#1 NSURLSession简介
1.NSURLSession是苹果为我们提供的一套新的网络处理库。
--NSURLSession负责接收和发送请求;
--NSURLSessionConfiguration负责配置session属性;
--Delegate负责监听网络操作中发生的事件
--NSURLSessionTask负责实际的工作:获取数据,上传和下载文件。
总的说来,NSURLSession通过两种方式来获取数据:通过completion handler或者代理方法。
2.NSURLSession优点在于:
--接口简单。不用担心之前NSURLConnection使用复杂的问题
--能满足我们的基本的网络请求需求。(与AFNetWorking没有区别,但一些加强功能除外)
--系统原生提供,不用做任何额外的导入操作,就可直接使用。
3.与Alamofire对比,不足在于:没有提供很方便的自动数据类型转换。比如,Alamofire 中可以自动将服务端返回的 JSON 数据识别并解析出来,而使用 NSURLSession 则需要自己来完成。
4.示例
使用NSURLSession.sharedSession()来获取NSURLSession的实例,然后调用dataTaskWithURL()方法传入url,最后在闭包中处理请求返回的结果。
必须手动调用resume()方法才会开始请求。因为NSURLSession默认是不启动resume()的。
#2 NSURLSession详细接口
NSURLSession本身是不会进行请求的,只有通过创建task的形式进行网络请求。一个NSURLSession可以创建多个task,并且这些task之间的cache和cookie是共享的。
--NSURLSessionDataTask:这就是刚才创建的data task,它用于读取服务端的简单数据,不如JSON数据
--NSURLSessionDownLoadTask:文件下载。针对大文件的网路请求做了一些处理,如:下载进度,断点续传。
--NSURLSessionUpLoadTask:文件上传。供服务端发送文件类型的数据使用。
(1)下载文件示例
使用downloadTaskWithURL方法来下载文件,这个方法的闭包中会接受一个location参数,它表示下载好的文件的存放位置。
注意:downloadTaskWithURL会将文件保存在一个临时目录中,location指向这个临时目录的位置。如果要持久保存文件,需将此文件从临时目录中移动出来。
(2)上传文件示例.使用uploadTaskWithRequest方法
#3 NSURLSessionConfiguration
1.为什么需要用NSURLSessionConfiguration?
用NSURLSession.sharedSession()方法创建的实例是全局的,没有代理对象,功能受限--比如说,不能检测下载速度,不能设置后台的下载机制。
所以,我们需要用NSURLSessionConfiguration对象来配置NSURLSession实例。
NSURLSession定义了两个配置方法:
--init(configuration:)
--init(configuration:delegate:delegateQueue:)
2.NSURLSessionConfiguration的三个默认初始化方法
--defaultSessionConfiguration:默认配置,使用全局的缓存,cookie信息。
--ephemeralSessionConfiguration:私有的Session。不会对缓存或cookie进行存储。相当于浏览器的隐私模式。
--backgroundSessionConfiguration:当应用切换到后台时,网络操作依然可以继续进行。
3.一旦用配置好的 NSURLSessionConfiguration 初始化 NSURLSession 实例后,就不能修改这个 NSURLSession 相关的配置了。所以,一切的配置操作都放在初始化 NSURLSession 之前。
#4 Delegate
--NSURLSessionDelegat作为所有代理的基类,定义了网络请求最基础的代理方法
--NSURLSessionTaskDelegate定义的网络请求任务相关的代理方法
--NSURLSessionDownloadDelegate用于下载任务相关的代理方法,比如查看下载进度
--NSURLSesssionDataDelegate用于普通数据任务和上传任务
#5 Demo
1.查询歌曲
--声明一个session常量和一个data task变量
--更新searchBarSearchButtonClicked(_:)方法
运行一下,现在是这样的!
2.下载歌曲
(1)新建一个文件,命名为Download。
(2) 添加一个变量,来存储urls和Download之间的映射关系。
(3)创建一个download task
思路是:配置session,配置delegate,更新开始下载的方法
--在ViewDidLoad()方法前声明变量.
问题一:lazy修饰符什么作用?表示这个属性是延迟加载的。除了能节省内存分配时间优化性能--在需要的时候downloadsSession才被创建出来;更重要的是,它能让你在self还没初始化的时候,就能将self作为delegate 参数传给构造器。
问题二:delegateQueue的参数为什么是nil?这能让session创建一个serial operation queue,来实现delegate方法和completion handler方法。
--实现NSURLSessionDownloadDelegate方法.当下载完成时,在控制台输出“Finished downloading”
--更新开始下载的方法.
3.保存和播放歌曲
当一个download task完成后,URLSession(_:downloadTask:didFinishDownloadingToURL:)方法提供了临时文件位置的URL。你需要做的是,在这个方法返回结果前,将这个URL移到app的沙盒容器目录中。同样,你需要从字典里将正在下载的download移走,并更新table view。
实现思路是:找出有request url歌曲的index --清除临时文件位置上的文件--将文件从临时文件位置复制到本地路径--移除activeDownloads数组中的download--更新table view
--添加一个方法,它会返回在searchResults列表中的歌曲的index。遍历searchResults数组,找出已经有url的歌曲。
--更新delegate方法
运行一下,在console里,你可以看到destinationURL
在模拟器里,点击下载好的歌曲,便能进行播放啦!
4. 查看下载进度
--添加代理方法
--更新cell配置。找到tableView(_:cellForRowAtIndexPath:)方法。
现在歌曲下载是这样的:
5.暂停,继续,取消下载
--添加这三个方法。
暂停下载和取消下载的不同之处在于暂停下载还会产生resumeData。
在继续下载和暂停下载方法中,isDownLoading作为flag标记,用来表示下载是否已经开始。
--更新cell配置方法。cell有两个button,一个button在“resume”和“pause”之间切换,另外一个button的title为“cancel”。
运行一下,现在是这样的
完结。
项目地址:github.com/Paganarchitect/iOS_tutorial_exercises_RayWenderlich.git