2017-03-13 3 views
1

Je souhaite suivre la progression des vidéos mises en ligne via une requête de flux avec UIProgressView. Malheureusement, je n'utilise pas Alamofire, donc je ne suis pas sûr si URLSession a cette capacité. Ci-dessous le code pertinent de mon application.Télécharger des demandes de diffusion et UIProgressView, Swift 3

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 définit correctement le UIProgressView pour indiquer que le téléchargement est terminé, cependant, est didSendBodyData affichant des valeurs supérieures à 1 par le calcul uploadProgress.

C'est la première fois que j'utilise une requête de flux, alors j'espère avoir simplement passé sous silence quelque chose que vous pourriez nous aider à souligner. Voici la structure de ma demande aussi pour référence.

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() 

Merci beaucoup pour votre contribution et votre aide.

Répondre

1

La lecture de la documentation a permis de déterminer que les objets de flux ne prennent pas en charge totalBytesExpectedToSend. Il peut s'agir d'un hack, mais l'utilisation de la fonctionnalité NSData.length du fichier permet un suivi de progression correct. Ainsi, pour les requêtes de flux utilisant URLSession, la progression peut être suivie en utilisant didSendBodyData, avec let uploadProgress: Float = Float(totalBytesSent)/Float(mediaSize), où mediaSize est NSData.length.

+0

comment vous diffusez avez-vous suivre sa progression? 'func urlSession (_ session: URLSession, tâche: URLSessionTask, didSendBodyData octetsSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64)' n'est jamais appelé dans les tâches de flux! – Martin

+0

Oups. J'ai juste oublié d'appeler 'streamTask.resume()' – Martin

0

La mise en œuvre

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

est la bonne façon de suivre la progression de la demande de cours d'eau. Mais si vous voulez maintenant totalBytesExpectedToSend, vous devez le dire au serveur. Alors n'oubliez pas de bien placer le en-tête Content-Length correct dans votre demande!

Voici la façon dont je crée la demande:

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()