一、说明
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,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