1

I've a chat view which is designed using UICollectionView. I've successfully implemented image upload functionality where whenever a user clicks an image using image picker the image gets uploaded to the server. Now I'm trying to add progress bar to each image to show the upload status. Currently what I've done is, whenever user picks an image using UIImagePicker my cell gets updated with the latest image and the collection view scrolls to bottom and in the URLsession delegate I catch the last cell and show the progress, but the problem is that, when I pick another image during the upload, the progress bar of both shows on the last cell. Below is my code for image picker and session delegate

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

        let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage 

        selectedImage = chosenImage

        //Some other code to update cell data

picker.dismissViewControllerAnimated(true, completion: { () -> Void in
            self.scrollToBottomAnimated(true)

        })

let qualityOfServiceClass = QOS_CLASS_BACKGROUND
        let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
        dispatch_async(backgroundQueue, {
            print("To run image upload in background")

            self.uploadImage(UIImageJPEGRepresentation(self.selectedImage!, 0.5)!, parameters:  self.createDictionaryForUploadImageDetails()) { (responseDict, error) -> () in

                if (responseDict != nil) {
                    print(responseDict!)
                }
                else
                {
                    if error != nil
                    {
                        Utilities.showAlertViewMessageAndTitle((error?.localizedDescription)!, title: "Error", delegate: [], cancelButtonTitle: "OK")
                    }

                }

            }
        })
}

NSURLSession Delegate

func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64)
    {
        let uploadProgress:Float = Float(totalBytesSent) / Float(totalBytesExpectedToSend)

        let section = self.numberOfSectionsInCollectionView(self.chatCollectionView) - 1
        let item = self.collectionView(self.chatCollectionView, numberOfItemsInSection:section)-1
        let finalIndexPath = NSIndexPath(forItem: item, inSection: section)

       if let selectedCell =  chatCollectionView.cellForItemAtIndexPath(finalIndexPath)
       {

            selectedCell.progressView.hidden = false
            selectedCell.progressView = Int(uploadProgress * 360)
            let progressPercent = Int(uploadProgress*100)
            selectedCell.progressView =  Int(uploadProgress) == 1
            print("Progress-\(progressPercent)% - \(progressView.hidden)")

        }
    }

How can I get the correct cell for each upload?

Wain
  • 118,658
  • 15
  • 128
  • 151
Francis F
  • 3,157
  • 3
  • 41
  • 79

1 Answers1

1

What you're lacking is a data model, so your current problem won't be the only one you have.

Your data model should be something like an array of custom classes, where the custom class has storage for the image to be displayed, but also information about wether the upload is in progress, the task that is processing it, the percentage complete, ...

Now, once this data model is in place it's simple for the task delegate to find the correct instance in your array to update with the progress details. The index in the array tells you which cell you need to update the UI for. And when you scroll the cells (so when new cell instances are requested to be created / updated) you still have all the progress information to display.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • 1
    Exactly. In other words, when a cell is about to be displayed it will show the current state of the model (image), e.g. if download is in progress, you'd display the current percentage and the cell will start listening to the model changes (delegate pattern). In each moment, you can have only one model delegate set since a single cell maps to a single model object. – Mercurial Mar 17 '16 at 14:24