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);
        }
    }
}
View Code

 

程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!
posted @ 2017-04-03 19:51  XYQ全哥  阅读(1342)  评论(0编辑  收藏  举报