一、说明
NSURLSession是OC中的会话类,在Swift中变成URLSession类,它们的实现方式是一样的,下面的示例就Swift语法进行讲解和介绍。
二、介绍:
URLSession 类支持3种类型的任务:加载数据、下载和上传。
加载数据:Data Task
下载数据:Downlaod Task
上传数据:Upload Task
毫无疑问,Session Task是整个URLSession架构的核心目标。
三。 加载数据:Data Task1. URLSession的URLSessionDataDelegate模式下载网络封装 (包含图片的增量下载)
import Foundation
import UIKit
public typealias SwiftClosure = ((_ data:Data? , _ progressValue:Float, _ error: Error?) -> Void)
class LJSessionRequestManager: NSObject{
/**
* 定义闭包属性,可选类型
*/
public var callBackClosure : SwiftClosure?
func sessoinDownload(_ url: String, _ method : String , _ callback: @escaping SwiftClosure)
{
callBackClosure = callback
//1、创建URL下载地址
let url:URL! = URL(string:url);
//2、创建Request对象
var urlRequest:URLRequest = URLRequest(url:url);
urlRequest.httpMethod = method
//不需要缓存
urlRequest.cachePolicy = .reloadIgnoringLocalCacheData
//3、创建会话
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config, delegate:self, delegateQueue: nil)
//4、下载任务 -- URLSessionDataDelegate 模式
let loadDataTask = session.dataTask(with: urlRequest)
//5、启动任务
loadDataTask.resume()
}
//初始化一个data,用来存储下载下来的数据
private var _responseData: NSMutableData!
var responseData: NSMutableData!{
get{
if _responseData == nil {
_responseData = NSMutableData()
}
return _responseData
}
set{
self._responseData = newValue
}
}
}
extension LJSessionRequestManager:URLSessionDataDelegate
{
@available(iOS 7.0, *)
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Swift.Void)
{
//允许继续加载数据
completionHandler(.allow)
}
@available(iOS 7.0, *)
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
{
//每次获取的data在此拼装
print("Data......\(data)")
self.responseData.append(data)
let currentBytes :Float = Float(self.responseData.length)
let allTotalBytes :Float = Float((dataTask.response?.expectedContentLength)!)
let proValu :Float = Float(currentBytes/allTotalBytes)
print("----下载进度:------\(proValu*100)%");
if callBackClosure != nil ,((dataTask.response?.expectedContentLength) != nil)
{
//避免循环引用,weak当对象销毁的时候,对象会被指定为nil
//weak var weakSelf = self //对象推到,省略了ViewController
weak var weakSelf : LJSessionRequestManager? = self //等同与上面的表达式
DispatchQueue.main.async
{
//将接收的数据结果回调到前台,用于进度展示,动态展示下载的图片
weakSelf?.callBackClosure!(self.responseData as Data,proValu ,nil)
}
}
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
{
if callBackClosure != nil ,let data = self.responseData{
weak var weakSelf : LJSessionRequestManager? = self
DispatchQueue.main.async
{
print("数据下载完毕")
//将接收的数据结果回调到前台,用于进度展示
weakSelf?.callBackClosure!(data as Data ,1.0 ,nil)
}
}
}
}
import Foundation
import UIKit
class LJNetImageViewController: TFBaseViewController {
var progressView : UIProgressView?
var progressValue : Float = 0.0
var ljImageView : UIImageView?
var ljDownLoadManage : LJSessionRequestManager?
var imageUrlArray = ["https://raw.githubusercontent.com/onevcat/Kingfisher/master/images/kingfisher-\(/*indexPath.row +*/ 2).jpg",
"http://image.nationalgeographic.com.cn/2015/0121/20150121033625957.jpg",
"http://image.nationalgeographic.com.cn/2017/0703/20170703042329843.jpg",
"http://image.nationalgeographic.com.cn/2017/0702/20170702124619643.jpg",
"http://image.nationalgeographic.com.cn/2017/0702/20170702124619643.jpg"]
override func viewDidLoad() {
super.viewDidLoad()
self.setTopNavBarTitle("图片下载")
self.setTopNavBackButton()
self.createDownLoadBtn()
self.createProgessView()
self.createImageView()
}
//MARK: -- UI
func createDownLoadBtn() {
let downLoadBtn = UIButton(frame: CGRect(x: (SCREEN_WIDTH - 100)/2.0, y: 120, width: 100, height: 40))
downLoadBtn .setTitle("down load", for: UIControlState())
downLoadBtn .addTarget(self, action: #selector(LJNetImageViewController.btnClicked(_:)), for: UIControlEvents.touchUpInside)
downLoadBtn.backgroundColor = UIColor.gray
self.view.addSubview(downLoadBtn)
}
//MARK: 进度条
func createProgessView() {
progressView = UIProgressView.init(progressViewStyle: .default)
progressView?.frame = CGRect(x: 0, y: 65, width: SCREEN_WIDTH, height: 1)
progressView?.progressTintColor = UIColor.red
progressView?.trackTintColor = UIColor.black
self.view.addSubview(progressView!)
}
func createImageView(){
ljImageView = UIImageView(frame: CGRect(x: (SCREEN_WIDTH - 200)/2.0, y: 180, width: 200, height: 200))
self.view.addSubview(ljImageView!)
}
func loadNetImage() {
ljDownLoadManage = LJSessionRequestManager()
ljDownLoadManage?.sessoinDownload(imageUrlArray[1], "GET", { (data, progressValue ,error) in
//避免循环引用,weak当对象销毁的时候,对象会被指定为nil
//weak var weakSelf = self //对象推到,省略了ViewController
weak var weakSelf : LJNetImageViewController? = self //等同与上面的表达式
DispatchQueue.main.async {
weakSelf?.progressView?.setProgress(progressValue, animated: true)
print("------进度打印:\(progressValue)")
if error == nil, data != nil{
let image = UIImage(data: data!)
weakSelf?.ljImageView?.image = image
}
}
})
}
func btnClicked(_ sender: UIButton)
{
//progressValue = progressValue + 0.1
//progressView?.setProgress(progressValue, animated: true)
self.loadNetImage()
}
}
控制台打印数据
Data......5544 bytes
----下载进度:------97.1827%
------进度打印:0.933892
Data......1386 bytes
----下载进度:------97.815%
------进度打印:0.940215
Data......1386 bytes
----下载进度:------98.4472%
------进度打印:0.946537
Data......2772 bytes
----下载进度:------99.7117%
Data......632 bytes
----下载进度:------100.0%
------进度打印:0.971827
------进度打印:0.97815
------进度打印:0.984472
数据下载完毕
------进度打印:0.997117
------进度打印:1.0