在TableView单元格Swift 4上显示文件上传进度

时间:2018-09-25 17:25:26

标签: ios swift uitableview

我正在从iCloud中选择文件并上传到AWS S3。我在Tableview单元格中列出了进度条上载状态的选定文件。每个单元格分别维护我正在维护的文件标题和加载进度。在这里,一切都差不多完成,但是如果我上传两个文件,则tableview的第一个单元格被冻结,第二个单元格完成上传进度。

我的上传功能

private func upload(file url: URL, keyname : String, exten: String) {
    let bucket = S3BucketName
    let key = keyname
    let contentType = "text/\(exten)"
    let expression = AWSS3TransferUtilityUploadExpression()
    expression.progressBlock = progressBlock

    let task = transferUtility.uploadFile(url,
                                          bucket: bucket,
                                          key: key,
                                          contentType: contentType,
                                          expression: expression,
                                          completionHandler: completionHandler)
    task.continueWith { (task) -> Any? in
        if let error = task.error {
            DispatchQueue.main.async {
                //self.infoLabel.text = "Error: \(error.localizedDescription)"
            }
            return nil
        }
        if let uploadTask = task.result {
            self.uploadTask = uploadTask
            DispatchQueue.main.async {

                //self.infoLabel.text = "Generating Upload File"

                //self.uploadRequests.append(self.uploadTask)
                self.tableView_util.reloadData()
            }
        }
        return nil
    }
}

Tableview单元格

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cellutil", for: indexPath) as! UtilityTableViewCell
        let item = tableArray[indexPath.row]
        cell.name_label_util.text = item.title
        cell.control_button_util.tag  = indexPath.row
        cell.control_button_util.addTarget(self, action: #selector(playpause), for: .touchUpInside)

        // MARK - Upload process
        progressBlock = { [weak self] task, progress in
            guard let strongSelf = self else { return }
            DispatchQueue.main.async {

                cell.loader_Line_util.progress = Float(progress.fractionCompleted)

                //NSLog(@"fraction completed: %f", progress.fractionCompleted);
                let percentageUploaded:Float = Float(progress.fractionCompleted) * 100
                cell.statusLabel_util.text! = NSString(format:"Uploading: %.0f%%",percentageUploaded) as String

                // Need to change
                if cell.statusLabel_util.text == "Uploading: 100%" {
                   cell.statusLabel_util.text = "File Successfully Uploaded!"
                    cell.loader_Line_util.progress = 1;
                    self?.tableView_util.reloadData()

                }
            }
        }

        completionHandler = { [weak self] task, error in
            guard let strongSelf = self else { return }
            if let error = error {
                DispatchQueue.main.async {
                }
                return
            }

1 个答案:

答案 0 :(得分:0)

好的,我不得不看一下AWS TransferUtility,以前从未使用过。我认为您需要重构一些东西。我在记事本中编写了此代码,很可能会出现语法错误,并且我将一些函数留空了,因为您可以在其中添加内容。

//create a class to track all your uploads in progress
Class UploadTaskTracker {

    let shared = uploadTaskTracker()

    private var tasks = [UploadTask]()

    func addTask( _ task: UploadTask){
        tasks.append(task)
    }

    fund updateTask( id: String, progress: Double){
        // get task from array and update progress value
    }

    func completeTask(id: String) {
        // remove task from tasks array
        // send out a notification to trigger tableview to reload data
    }

    func activeTasks() -> Int {
        return tasks.count
    }

    func taskAt(_ indexPath: IndexPath) -> UploadTask{
        // check for out of bounds 
        // return task
    }
    }

Class UploadTask {

    var id : String
    var progress : Double

}



// and when you start an upload task, change your expression progress block
// (and remove it from the cell.  This should all be happening in another 
// class and not be associated with your tableview 

let guid = UUID()
let uploadTask = UploadTask.init(id: guid, progress: 0.0)
UploadTaskTracker.shared.addTask(uploadTask_

expression.progressBlock = {(task, progress) in

    UploadTaskTracker.shared.updateTask(id: guid, progress: progress)
 }



// then in table view controller
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return UploadTaskTracker.shared.activeTasks()
    }

//And then in 
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // dequeue custom uitableviewcel
    let uploadTask = UploadTaskTracker.shared. taskAt( indexPath)
    cell.load(uploadTask)

}

// create a custom uitableviewcell class
class customCell: UITableViewCell {

    @IBOutlet weak var someLabel: UILabel!
    var observers = [NSKeyValueObservation]()

    override func prepareForReuse() {
        // clear previous UI to reduce chance of user seeing obsolete text or image
        super.prepareForReuse()
        stopObservers()
    }

    func stopObservers(){
        for observer in observers{
            observer.invalidate()
        }
        observers.removeAll()
    }

    func load(_ uploadTask: UploadTask ) {

        let observer = uploadTask.observe(\.progress, options: [.initial, .new]) { [weak self] (uploadTask, change) in

            DispatchQueue.main.async {          
                someLabel.text = “\(uploadTask.progress)”
            }
        }
        observers.append(observer)
}