上传流请求和UIProgressView,Swift 3

时间:2017-03-13 14:34:52

标签: swift3 nsurlsession uiprogressview

我想通过UIProgressView跟踪通过流请求上传的视频的进度。不幸的是,我没有使用Alamofire,因此我不确定URLSession是否具备此功能。以下是我的申请中的相关代码。

func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {

    let uploadProgress:Float = Float(totalBytesSent) / Float(totalBytesExpectedToSend)
    let uploadCell = contentTableView.cellForRow(at: IndexPath(row: 0, section: 0)) as! NewContentCell
    uploadCell.uploadProgressView.progress = uploadProgress


}

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    let uploadCell = contentTableView.cellForRow(at: IndexPath(row: 0, section: 0)) as! NewContentCell
    uploadCell.uploadProgressView.progress = 1.0
}

didCompleteWithError正确设置UIProgressView以指示上传已完成,但didSendBodyData通过uploadProgress计算返回的值大于1。

这是我第一次使用流媒体请求,所以我希望我只是掩饰一些你可以帮忙指出的东西。这是我的请求的结构以供参考。

let request = NSMutableURLRequest(url: NSURL(string: "\(requestUrl)")! as URL,
                                          cachePolicy: .useProtocolCachePolicy,
                                          timeoutInterval: 10.0)
        request.httpMethod = "POST"
        request.allHTTPHeaderFields = headers
        request.httpBodyStream = InputStream(data: body as Data)

        let configuration = URLSessionConfiguration.default
        let session = URLSession(configuration: configuration, delegate: self, delegateQueue: OperationQueue.main)
        let dataTask = session.uploadTask(withStreamedRequest: request as URLRequest)
        dataTask.resume()

非常感谢您的投入和帮助。

2 个答案:

答案 0 :(得分:1)

进一步阅读文档,发现流对象不支持totalBytesExpectedToSend。它可能是一个黑客攻击,但只使用文件的NSData.length功能可以实现正确的进度跟踪。因此,对于使用URLSession的流请求,可以使用didSendBodyDatalet uploadProgress: Float = Float(totalBytesSent) / Float(mediaSize)来跟踪进度,mediaSizeNSData.length

答案 1 :(得分:0)

实施

public func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64)

是跟踪流请求进度的正确方法。

但是如果您现在要totalBytesExpectedToSend,则必须告诉服务器。所以不要忘记在请求中设置正确的Content-Length标题!

以下是我创建请求的方式:

var request = URLRequest(url: url)
request.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type")
request.addValue(String(dataToUpload.count), forHTTPHeaderField: "Content-Length") // <-- here!
request.httpBodyStream = InputStream(data: dataToUpload)
var task = session.uploadTask(withStreamedRequest: request)
task?.resume()