美文网首页
URLSession基本使用

URLSession基本使用

作者: 思绪_HY | 来源:发表于2018-11-05 15:14 被阅读100次

    简述

    由于最近想要研究下Swift中第三方网络请求库Alamofire的使用和实现,而Alamofire中又是使用URLSession进行封装的,所以有必要去先深入了解下URLSession。URLSession等同于NSURLSession,只是前者是Swift中的名字,后者是OC中的名字,他们之间是可以直接相互转换的。NSURLSession是同iOS7一同推出的,主要是对NSURLConnection进行了重构和优化,并且NSURLConnection在iOS 9的时候也已经被废弃,所以NSURLSession是NSURLConnection的取代者。

    URLSession层级

    再使用之前我们先看一下URLSession的层级结构

    • URLSession
    • URLSessionconfiguration
    • URLSessionTask
    • URLSessionDataTask
      • URLSessionUploadTask
    • URLSessionDownloadTask
    • URLSessionStreamTask

    URLSession相关的代理方法

    • URLSessionDelegate
    • URLSessionTaskDelegate
    • URLSessionDataDelegate
    • URLSessionDownloadDelegate
    • URLSessionStreamDelegate

    URLSession使用的时候也会用到相关的若干类:

    • NSURL
    • NSURLRequest
    • URLResponse
    • HTTPURLResponse
    • CachedURLResponse

    创建URLSession

    使用URLSession需要先创建一个URLSessionConfiguration实例,URLSessionConfiguration主要是URLSession上传或者下载数据时候的一些相关的配置,例如超时时间、缓存策略、等等,当然你也可以在URLRequest中进行一些相关配置

    let sessionConfigure = URLSessionConfiguration.default 
    sessionConfigure.httpAdditionalHeaders = ["Content-Type": "application/json"]
    sessionConfigure.timeoutIntervalForRequest = 30
    sessionConfigure.requestCachePolicy = .reloadIgnoringLocalCacheData
    let session = URLSession(configuration: sessionConfigure)
    

    URLSessionConfiguration创建时候有三种选择,默认的、短暂的、和后台的,这个需要根据自己的需求去创建

    使用URLSession

    由于URLSession把网络任务进行了细分,所以我们可以根据我们的需求,选择不同的Task

    普通数据请求

    普通的 json 数据可以使用URLSessionDataTask

     guard let url =  URL(string: "http://rap.taobao.org/mockjsdata/13552/provincelist") else {
            return
        }
     let urlRequest = URLRequest(url: url)
     let dataTask = session.dataTask(with: urlRequest) { (data, response, error) in
         guard let resultData = data else {
             return
     }
      do {
         let jsonObject = try JSONSerialization.jsonObject(with: resultData, options: .mutableLeaves)
             print(jsonObject)
       } catch {
             print("解析错误!")
       }
     }
    

    获取到 dataTask 以后需要使用 resume() 函数来恢复或者开始

    dataTask.resume()
    

    这样请求到数据后就会在闭包中返回数据,我们可以在闭包中进行数据处理。

    上传数据

    URLSession上传数据需要用到uploadTask(with request: URLRequest, from bodyData: Data?, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Swift.Void) -> URLSessionUploadTask函数,bodyData就是要上传的数据,非表单数据不需要对数据进行处理,使用这个函数上传的时候会自动忽略httpBodyhttpStream,上传表单数据的时候要复杂一些,需要先对数据进行一些处理,如下:

        let boundary = "Ju5tH77P15Aw350m3"
        let crlf = "\r\n"
        let initial = "--\(boundary)\(crlf)"
        let final = "\(crlf)--\(boundary)--\(crlf)"
        let contentDisposition = "Content-Disposition: form-data; name=\"image\";filename=\"image5.png\"\(crlf)"
        let mimeType = "Content-Type=image/png\(crlf)"
        var bodyData = Data()
        guard let initialData = initial.data(using: .utf8) else {
            return
        }
        guard let finalData = final.data(using: .utf8) else {
            return
        }
        guard let contentDispositionData = contentDisposition.data(using: .utf8) else {
            return
        }
        guard let mimeTypeData = mimeType.data(using: .utf8) else {
            return
        }
        
        bodyData.append(initialData)
        bodyData.append(contentDispositionData)
        bodyData.append(mimeTypeData)
        guard let imageData = UIImageJPEGRepresentation(#imageLiteral(resourceName: "Image"), 0.5) else {
            return
        }
        bodyData.append(imageData)
        bodyData.append(finalData)
        
        let sessionConfigure = URLSessionConfiguration.ephemeral
        sessionConfigure.httpAdditionalHeaders = ["Content-Type": "multipart/form-data; boundary=\(boundary)"]
        sessionConfigure.timeoutIntervalForRequest = 30
        sessionConfigure.requestCachePolicy = .reloadIgnoringLocalCacheData
        let session = URLSession(configuration: sessionConfigure)
        guard let url = URL(string: "http://picupload.service.weibo.com/interface/pic_upload.php") else {
            return
        }
        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = "POST"
        let task = session.uploadTask(with: urlRequest, from: bodyData) { (data, response, error) in
            guard let data = data else {
                return
            }
            let htmlString = String.init(data: data, encoding: .utf8)
            print(htmlString ?? "html")
            print(response ?? "response")
        }
        task.resume()
    

    这是使用上传函数的代码,由于上传数据的时候我们的请求头中Content-typemultipart/form-data,所以我们需要对上传的的数据进行一些处理,添加boundary这个表示每段数据的边界,Content- Disposition表示的是服务器端要对对数据进行的处理,添加的数据格式需要跟上边的一致,添加的每一行都需要以\r\n结尾。

    上边主要说明的是直接以Data的形式上传的,当然也可以提供文件路径上传文件,使用方法类似。

    下载数据

    下载数据的时候需要用到downloadTask(with url: URL, completionHandler: @escaping (URL?, URLResponse?, Error?) -> Swift.Void) -> URLSessionDownloadTask,下载成功以后会在闭包中返回一个存在 tem 文件夹的文件URL,由于这个文件夹下的文件随时可能被清空,所以需要把文件移动到另一个文件夹下

            guard let url = URL(string: "http://172.16.2.254/php/phonelogin/image.png") else {
            return
        }
        let session = URLSession.shared
        let downloadTask = session.downloadTask(with: url) { (temURL, response, error) in
            let persistentPath = NSTemporaryDirectory().appending("/\(response?.suggestedFilename ?? "image.png")")
            guard let temURL = temURL else {
                print("源URL不存在")
                return
            }
            guard let persistentURL = URL(string: persistentPath) else {
                print("目标路径不存在")
                return
            }
            do {
                try FileManager.default.moveItem(at: temURL, to: persistentURL)
            } catch {
                print("移动失败")
            }
            
        }
        downloadTask.resume()
    

    以上就是URLSession的基本使用,后续会对URLSession的代理方法,以及URLSession推流,URLCache、Cookie使用等进行梳理介绍...

    未完待续

    相关Demo:https://github.com/jiahongyuan5/URLSessionDemo/archive/master.zip

    相关文章

      网友评论

          本文标题:URLSession基本使用

          本文链接:https://www.haomeiwen.com/subject/kkysxqtx.html