我想跟踪使用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()
非常感谢您的输入和帮助。
实施
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()
进一步读取文档,发现流对象不支持totalBytesExpectedToSend
。它可能是一个黑客,但是只需使用文件的NSData.length
功能即可进行正确的进度跟踪。因此,对于使用urlsession的流请求,可以使用didSendBodyData
,与let uploadProgress: Float = Float(totalBytesSent) / Float(mediaSize)
一起跟踪进度,其中mediaSize
为NSData.length
。