2017-12-29 38 views
0

Ich wette, das ist eine ziemlich grundlegende Frage, aber ich kann das nicht zur Arbeit bekommen. Ich lade ein Bild von AWS S3 herunter, bin in der Lage, den Fortschritt des Downloads zu ermitteln, und kann eine Aktualisierung der Fortschrittsvariablen entsprechend vornehmen. Ich kann jedoch keinen Weg finden, einen Fortschrittsbalken basierend auf dieser Variable zu animieren.AWS S3 Download mit iOS kreisförmigen Fortschrittsbalken

Die (zugegebenermaßen klobig) Code ist wie folgt:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    self.refresh() //re-gets user info. Having trouble with AWS randomly claiming I'm attempting to download using UnAuth even though I am logged in 
    tableView.deselectRow(at: indexPath, animated: true) 
    self.downloadProgressView.isHidden = false 
    self.proprietaryObject = proprietaryObjects[indexPath.row] 
    let expression = AWSS3TransferUtilityDownloadExpression() 
    expression.progressBlock = {(task, progress) in DispatchQueue.main.async(execute: { 
     self.progress = progress 
    }) 
    } 

    let transferUtility = AWSS3TransferUtility.default() 
    let resource = "\(self.proprietaryObject?.value1 ?? "NA")_\(self.proprietaryObject?.value2 ?? "NA")_\(self.proprietaryObject?.firstName ?? "NA")_\(self.proprietaryObject?.lastName ?? "NA")" 
    let type = "jpeg" 
    self.downloadingFileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("\(resource).\(type)") 
    transferUtility.download(to: self.downloadingFileURL!, bucket: AWSS3BucketName, key: "\(resource).\(type)", expression: expression, completionHandler: { (task, URL, Data, Error) in 
     if Error != nil { 
      print (Error!) 
     } 
     if let data = Data { 
      print("Data: \(data)") 
      let image = UIImage(data: data) 
      self.downloadedImage = image 
     } 
    }).continueWith(executor: AWSExecutor.default()) { (task) -> Any? in 
     if let error = task.error { 
      print("download error: \(error)") 
      self.refresh() 
     }else { 
      print("Download started") 
      print("User: \(self.user?.username ?? "NO USER")") 
      self.animatePath() 

     } 
     return nil 
    } 
} 
func animatePath() { 
    print("Animation Started") 
    if !(self.view.subviews.contains(downloadProgressView)) { 
     self.view.addSubview(downloadProgressView) 
     downloadProgressView.center = self.view.center 
     self.downloadProgressView.isHidden = false 
     self.downloadProgressView.layer.addSublayer(self.shapeLayer) 
    }else { 
     self.view.bringSubview(toFront: self.downloadProgressView) 
     self.downloadProgressView.isHidden = false 
     downloadProgressView.center = self.view.center 
     if !((downloadProgressView.layer.sublayers?.contains(self.shapeLayer))!) { 
      self.downloadProgressView.layer.addSublayer(self.shapeLayer) 
     } 

    } 
    func animate() { 
     if self.progress?.fractionCompleted == nil { 
      self.fraction = 0 
     }else { 
      self.fraction = 0 + (self.progress?.fractionCompleted)! 
     } 
     let animation = CABasicAnimation(keyPath: "strokeEnd") 
     animation.fromValue = CGFloat(self.shapeLayer.strokeEnd) 
     animation.toValue = CGFloat(self.fraction!) 
     animation.duration = 0.2 
     animation.fillMode = kCAFillModeForwards 
     self.shapeLayer.strokeEnd = CGFloat(self.fraction!) 
     self.shapeLayer.add(animation, forKey: "animation") 
    } 

    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1) , execute: { 
     //the one second delay gives self.progress.fractionCompleted time to be non-nil 
     repeat { 
      animate() 
      print("Completed: \((self.progress?.fractionCompleted)! * 100)%") 
     } while self.fraction! < 1 

     if self.fraction == 1 { 
      print("fraction achieved 100%. resetting to 0%") 
      self.fraction = 0 
      self.progress = nil 
      self.performSegue(withIdentifier: "proprietarySegue", sender: self) 
     } 
    }) 
} 

Die Konsole meldet sich der Inkrementierung „.fractionCompleted“% ganz gut und wenn es 100% erreicht hat es die Segue auszuführen. Das Bild in der folgenden ViewController UIImageView ist in der Tat das heruntergeladene Bild (Override-Vorbereitung für den nicht gezeigten Kanal). Aber ich bekomme nur einen kurzen Blick auf den Fortschrittskreis. Gewöhnlich zeigt es keinen Fortschritt, dann führt es eine Überfahrt durch. Unmittelbar nach dem ersten Übergang wird für jeden nachfolgenden Download entweder der DownloadProgressView nicht angezeigt oder zeigt eine 100% ige Vervollständigung, bevor er verschwindet.

Ich habe das Gefühl, ich mache etwas grundsätzlich falsch und/oder es hat etwas mit dem Thread zu tun ...?

Jede Hilfe wäre willkommen.

Antwort

0

self.animatePath() wurde im Fertigstellungsblock von transferUtility aufgerufen. Aus diesem Grund wird die Animation am Ende des Downloads stattfinden und die Übertragung wird durchgeführt.

Versuchen:

let expression = AWSS3TransferUtilityDownloadExpression() 
expression.progressBlock = {(task, progress) in 
    DispatchQueue.main.async(execute: { 
     self.progress = progress 
     self.animatePath() 
    }) 
} 
+0

Das war es. Danke, Vineet! Der Aufruf animatePath() wurde in den Fortschrittsblock verschoben und der Wiederholungsanimationsblock entfernt. Ich füge hinzu, dass, obwohl es technisch unnötig ist, ich in der Verzögerung von einer Sekunde gegangen bin, weil es in diesem Fall sauberer aussieht, als keinen zu haben. Außerdem musste ich "self.shapeLayer.strokeEnd = 0" zum "if self.fraction == 1" -Block hinzufügen. – End3r117

Verwandte Themen