swift3.0:NSURLSession的使用
一、说明
NSURLSession是OC中的会话类,在Swift中变成URLSession类,它们的实现方式是一样的,下面的示例就Swift语法进行讲解和介绍。
二、介绍:
URLSession 类支持3种类型的任务:加载数据、下载和上传。
加载数据:Data Task
下载数据:Downlaod Task
上传数据:Upload Task
毫无疑问,Session Task是整个URLSession架构的核心目标。
三、示例
第1种Data Task用于加载数据。
使用全局share和func dataTask(...)->URLSessionDataTask方法创建。
//MARK - URLSessionDataTask func sessionLoadTsk() { //1、创建URL对象; let url:URL! = URL(string:"http://api.3g.ifeng.com/clientShortNews?type=beauty"); //2、创建Request对象; let urlRequest:URLRequest = URLRequest(url:url); //3、创建会话 let session = URLSession.shared //4、通过创建任务 let dataTask = session.dataTask(with: urlRequest) { (data:Data?, response:URLResponse?, error:Error?) in if(error != nil){ print(error?.localizedDescription); }else{ //let jsonStr = String(data: data!, encoding:String.Encoding.utf8); //print(jsonStr) do { let dic = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) print(dic) } catch let error{ print(error.localizedDescription); } } } as URLSessionDataTask //5、启动任务 dataTask.resume() }
解析结果:
{ body = ( { cThumbnail = "http://d.ifengimg.com/w166_h120/p1.ifengimg.com/ifengiclient/ipic/2017040117/swoole_location_1af16fdc4e8301e229769e7892877895_3742809557_size202_w690_h1155.jpg"; cid = 1; comments = 0; commentsUrl = "http://share.iclient.ifeng.com/news/sharenews.f?&fromType=spider&aid=301352"; commentsall = 0; content = ""; ctime = "2017-04-01 18:00:02"; id = "shortNews_301352"; img = ( { size = { height = 803; width = 480; }; url = " ........... ........... ........... }
第2种Download Task用于完成下载文件的任务。
如果不需要获取进度,就使用全局的share和func downloadTaskWithRequest(...)->NSURLSessionDownloadTask方法创建。
//MARK - URLSessionDownloadTask func sessionSimpleDownLoad(){ //1、创建URL下载地址 let url:URL! = URL(string:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1491221913316&di=f416fd4642c4b63c8b82521031ce8529&imgtype=0&src=http%3A%2F%2Fimg.tupianzj.com%2Fuploads%2Fallimg%2F160309%2F9-16030Z92137.jpg"); //2、创建Request对象 let urlRequest:URLRequest = URLRequest(url:url); //3、创建会话 let session = URLSession.shared //4、通过创建任务 let downLoadTask = session.downloadTask(with: urlRequest) { (location:URL?, response:URLResponse?, error:Error?) in //location位置转换 let locationPath = location?.path //复制到我们自己的目录中 let documentPath:String = "/Users/xiayuanquan/Desktop/demo1.png" //创建文件管理器 let fileManager:FileManager = FileManager.default do{ try fileManager.moveItem(atPath: locationPath!, toPath: documentPath) }catch let error{ print(error.localizedDescription); } } as URLSessionDownloadTask //5、启动任务 downLoadTask.resume() }
下载结果:显示在桌面
如果需要获取进度,就使用自定义的URLSession和func downloadTaskWithRequest(...)->NSURLSessionDownloadTask方法创建。
1、创建会话单例
//创建一个下载模式--单例实例 public extension DispatchQueue { private static let _onceToken = NSUUID().uuidString private static var _onceTracker = [String]() public class func once(block:()->Void) { objc_sync_enter(self) defer { objc_sync_exit(self) } if _onceTracker.contains(_onceToken) { return } _onceTracker.append(_onceToken) block() } }
2、执行下载任务
//MARK - URLSessionDownloadTask func currentSession() -> URLSession { var currentSession:URLSession? DispatchQueue.once() { let config = URLSessionConfiguration.default currentSession = URLSession(configuration: config, delegate:self, delegateQueue: nil) } return currentSession!; } func sessoinProgressDownload() { //1、创建URL下载地址 let url:URL! = URL(string:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1491221913316&di=f416fd4642c4b63c8b82521031ce8529&imgtype=0&src=http%3A%2F%2Fimg.tupianzj.com%2Fuploads%2Fallimg%2F160309%2F9-16030Z92137.jpg"); //2、创建Request对象 let urlRequest:URLRequest = URLRequest(url:url); //3、创建会话 let session = currentSession() //4、下载任务 let downloadTask = session.downloadTask(with: urlRequest) //5、启动任务 downloadTask.resume() } }
3、监听代理方法
// MARK - URLSessionDownloadDelegate extension URLSessionController:URLSessionDownloadDelegate{ //下载进度 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { //获取进度 let written:CGFloat = CGFloat(bytesWritten) let total:CGFloat = CGFloat(totalBytesWritten) let pro:CGFloat = written/total print("----下载进度:------\(pro)"); } //下载偏移 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) { //主要用于暂停续传 } //下载结束 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { //location位置转换 let locationPath = location.path //复制到我们自己的目录中 let documentPath:String = "/Users/xiayuanquan/Desktop/demo1.png" //创建文件管理器 let fileManager:FileManager = FileManager.default do{ try fileManager.moveItem(atPath: locationPath, toPath: documentPath) }catch let error{ print(error.localizedDescription); } } }
下载结果:
----下载进度:------1.0 ----下载进度:------0.804931929103519 ----下载进度:------0.198212299707542 ----下载进度:------0.0266228298785133 ----下载进度:------0.025989494854822
第3种Upload Task用于完成上传文件的任务,与下载方法类似。
//使用URLSessionDataTask上传文件 func sessionUpload() { //1、创建URL上传地址,服务器自己搭建 var url:URL! = URL(string:"http://xxx.com/upload.php"); //2、创建Request对象 let urlRequest:URLRequest = URLRequest(url:url); //3、创建会话 let session = currentSession() //4、上传数据流 let docmentPath:String = "/Users/xiayuanquan/Desktop/demo1.png"; url = URL.init(string: docmentPath) do{ let imageData = try Data(contentsOf: url, options: Data.ReadingOptions.alwaysMapped) //5、创建上传任务 let uploadTask = session.uploadTask(with: urlRequest, from: imageData, completionHandler: { (data:Data?, response:URLResponse?, error:Error?) in //上传完毕后判断 print("上传完毕") }) //6、启动任务 uploadTask.resume() }catch let error{ print(error.localizedDescription); }
四、完整代码
// // URLSessionController.swift // NetWorkTest // // Created by 夏远全 on 2017/4/3. // Copyright © 2017年 夏远全. All rights reserved. // import UIKit class URLSessionController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } //第1种Data Task用于加载数据。 //使用全局share和func dataTask(...)->URLSessionDataTask方法创建。 //MARK - URLSessionDataTask func sessionLoadTsk() { //1、创建URL对象; let url:URL! = URL(string:"http://api.3g.ifeng.com/clientShortNews?type=beauty"); //2、创建Request对象; let urlRequest:URLRequest = URLRequest(url:url); //3、创建会话 let session = URLSession.shared //4、通过创建任务 let dataTask = session.dataTask(with: urlRequest) { (data:Data?, response:URLResponse?, error:Error?) in if(error != nil){ print(error?.localizedDescription); }else{ //let jsonStr = String(data: data!, encoding:String.Encoding.utf8); //print(jsonStr) do { let dic = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) print(dic) } catch let error{ print(error.localizedDescription); } } } as URLSessionDataTask //5、启动任务 dataTask.resume() } //第2种Download Task用于完成下载文件的任务。 //不需要获取进度,就使用全局的share和func downloadTask(...)->URLSessionDownloadTask方法创建。 //MARK - URLSessionDownloadTask func sessionSimpleDownLoad(){ //1、创建URL下载地址 let url:URL! = URL(string:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1491221913316&di=f416fd4642c4b63c8b82521031ce8529&imgtype=0&src=http%3A%2F%2Fimg.tupianzj.com%2Fuploads%2Fallimg%2F160309%2F9-16030Z92137.jpg"); //2、创建Request对象 let urlRequest:URLRequest = URLRequest(url:url); //3、创建会话 let session = URLSession.shared //4、通过创建任务 let downLoadTask = session.downloadTask(with: urlRequest) { (location:URL?, response:URLResponse?, error:Error?) in //location位置转换 let locationPath = location?.path //复制到我们自己的目录中 let documentPath:String = "/Users/xiayuanquan/Desktop/demo1.png" //创建文件管理器 let fileManager:FileManager = FileManager.default do{ try fileManager.moveItem(atPath: locationPath!, toPath: documentPath) }catch let error{ print(error.localizedDescription); } } as URLSessionDownloadTask //5、启动任务 downLoadTask.resume() } //第2种Download Task用于完成下载文件的任务。 //需要获取进度,就使用自定义的URLSession和func downloadTask(with request: URLRequest) -> URLSessionDownloadTask方法创建。 //MARK - URLSessionDownloadTask func currentSession() -> URLSession { var currentSession:URLSession? DispatchQueue.once() { let config = URLSessionConfiguration.default currentSession = URLSession(configuration: config, delegate:self, delegateQueue: nil) } return currentSession!; } func sessoinProgressDownload() { //1、创建URL下载地址 let url:URL! = URL(string:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1491221913316&di=f416fd4642c4b63c8b82521031ce8529&imgtype=0&src=http%3A%2F%2Fimg.tupianzj.com%2Fuploads%2Fallimg%2F160309%2F9-16030Z92137.jpg"); //2、创建Request对象 let urlRequest:URLRequest = URLRequest(url:url); //3、创建会话 let session = currentSession() //4、下载任务 let downloadTask = session.downloadTask(with: urlRequest) //5、启动任务 downloadTask.resume() } //第3种Upload Task用于完成上传文件的任务,与下载方法类似 //使用URLSessionDataTask上传文件 func sessionUpload() { //1、创建URL上传地址 var url:URL! = URL(string:"http://xxx.com/upload.php"); //2、创建Request对象 let urlRequest:URLRequest = URLRequest(url:url); //3、创建会话 let session = currentSession() //4、上传数据流 let docmentPath:String = "/Users/xiayuanquan/Desktop/demo1.png"; url = URL.init(string: docmentPath) do{ let imageData = try Data(contentsOf: url, options: Data.ReadingOptions.alwaysMapped) //5、创建上传任务 let uploadTask = session.uploadTask(with: urlRequest, from: imageData, completionHandler: { (data:Data?, response:URLResponse?, error:Error?) in //上传完毕后判断 print("上传完毕") }) //6、启动任务 uploadTask.resume() }catch let error{ print(error.localizedDescription); } } } //创建一个下载模式--单例实例 public extension DispatchQueue { private static let _onceToken = NSUUID().uuidString private static var _onceTracker = [String]() public class func once(block:()->Void) { objc_sync_enter(self) defer { objc_sync_exit(self) } if _onceTracker.contains(_onceToken) { return } _onceTracker.append(_onceToken) block() } } // MARK - URLSessionDownloadDelegate extension URLSessionController:URLSessionDownloadDelegate{ //下载进度 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { //获取进度 let written:CGFloat = CGFloat(bytesWritten) let total:CGFloat = CGFloat(totalBytesWritten) let pro:CGFloat = written/total print("----下载进度:------\(pro)"); } //下载偏移 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) { //主要用于暂停续传 } //下载结束 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { //location位置转换 let locationPath = location.path //复制到我们自己的目录中 let documentPath:String = "/Users/xiayuanquan/Desktop/demo1.png" //创建文件管理器 let fileManager:FileManager = FileManager.default do{ try fileManager.moveItem(atPath: locationPath, toPath: documentPath) }catch let error{ print(error.localizedDescription); } } }
程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!