使用S3下载功能快速更新tableview异步

时间:2016-02-17 18:59:31

标签: ios swift uitableview asynchronous uiimage

我有一个异步问题 - 我有一个从S3加载图像的函数,将它们存储到UIImages数组中(这里称为图像)

我还有一个tableview从firebase获取的数据加载其单元格,我的问题是,一旦异步完成加载,如何更新单元格图像?

我还担心图像队列与indexPath.row完全匹配,因为某些图像的加载速度可能比其他图像快。

 func download(key:String, myindex:NSIndexPath, myrow:Int) -> NSString {
    let path:NSString = NSTemporaryDirectory().stringByAppendingString("image.jpg")
    let url:NSURL = NSURL(fileURLWithPath: path as String)

    //    let downloadingFilePath = downloadingFileURL.path!
    let downloadRequest = AWSS3TransferManagerDownloadRequest()
    downloadRequest.bucket = "witnesstest/" + rootref.authData.uid
    downloadRequest.key = key
    downloadRequest.downloadingFileURL = url

    switch (downloadRequest.state) {
    case .NotStarted, .Paused:
        let transferManager = AWSS3TransferManager.defaultS3TransferManager()
        transferManager.download(downloadRequest).continueWithBlock({ (task) -> AnyObject! in
            if let error = task.error {
                if error.domain == AWSS3TransferManagerErrorDomain as String
                    && AWSS3TransferManagerErrorType(rawValue: error.code) == AWSS3TransferManagerErrorType.Paused {
                        print("Download paused.")
                } else {
                    print("download failed: [\(error)]")
                }
            } else if let exception = task.exception {
                print("download failed: [\(exception)]")
            } else {
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    let tempimage:UIImage = UIImage(contentsOfFile: path as String)!
                    print("dl ok")
                    self.Images.append(tempimage)

            })
            }
            return nil
        })

        break
    default:
        break
    }
    return path
}

和细胞:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell: MainWitnessTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("RIcell") as! MainWitnessTableViewCell

        // populate the cell
        let postitem = posts[indexPath.row]
        cell.postOwner.text = postitem.author
        cell.postContent.text = postitem.content
        cell.postDate.text = postitem.createon

        let myindex = indexPath
        let myrow = indexPath.row




       // cell.cellImage.image = Images[indexPath.row] // returns array index out of range

     //   download(postitem.imagekey, myindex: myindex, myrow: myrow)

    return cell
}

2 个答案:

答案 0 :(得分:0)

我建议你创建一个图像缓存和它们应该关联的索引,然后不是加载函数中的所有图像,而是创建表视图,然后针对特定的单元格询问对于来自服务器或缓存的图像(如果它已经存在),而不是尝试一次下载所有异步

答案 1 :(得分:0)

您可以在下载图像后设置imageView的图像,同时设置postitem的图像属性(假设您添加了一个)。我很难理解你的下载方法正在做的一切,但我认为你想要的东西是这样的:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell: MainWitnessTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("RIcell") as! MainWitnessTableViewCell

        // populate the cell
        let postitem = posts[indexPath.row]
        cell.postOwner.text = postitem.author
        cell.postContent.text = postitem.content
        cell.postDate.text = postitem.createon

        //postitem should also have a imageURL property or you should have some way of getting the image url.
        if post item.image == nil{
            dispatch_queue_t imageFetchQ = dispatch_queue_create("image fetcher", NULL)
            dispatch_async(imageFetchQ, ^{

               let imageData = NSData(contentsOfURL: postitem.imageURL)
               let image = UIImage(data: imageData)
               postitem.image = image
               dispatch_async(dispatch_get_main_queue(), ^{
                   //the UITableViewCell may have been dequeued and reused so check if the cell for the indexPath != nil
                   if tableView.cellForRowAtIndexPath(indexPath) != nil{
                       cell.imageView.image = image
                   }
    })

})





    return cell
}