swift 网络----利用URLSession的Data Task下载单张图片(包含图片的增量下载)

前端之家收集整理的这篇文章主要介绍了swift 网络----利用URLSession的Data Task下载单张图片(包含图片的增量下载)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一、说明

NSURLSession是OC中的会话类,在Swift中变成URLSession类,它们的实现方式是一样的,下面的示例就Swift语法进行讲解和介绍。

二、介绍:

URLSession类支持3种类型的任务:加载数据、下载和上传

加载数据:Data Task

下载数据:Downlaod Task

上传数据:Upload Task

毫无疑问,Session Task是整个URLSession架构的核心目标。

三。 加载数据:Data Task

1. 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)
            }
        }

    }
}


2. 下面demo界面(包含下载进度条)
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

原文链接:https://www.f2er.com/swift/321485.html

猜你在找的Swift相关文章