0

Hi I'm new with swift and parse.com, I'm trying do populate my array with already saved images in parse, try to use the dispatch_async but don't know how this works, heres the code:

//imageArray declaration in table:
var imageArray: Array<UIImage> = []


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell

    var query = PFQuery(className: "ParseClass")

    query.findObjectsInBackgroundWithBlock { ( objects: [AnyObject]?, error: NSError?) -> Void in

        if(error == nil) {

            let imageObjects = objects as! [PFObject]

            for object in objects! {

                let thumbNail = object["columnInParse"] as! PFFile

                thumbNail.getDataInBackgroundWithBlock ({ (imageData: NSData?, error: NSError?) -> Void in

                    if (error == nil) {

                        if let image = UIImage(data:imageData!) {

 //here where the error appears: Cannot invoke 'dispatch_async' with an argument list of type '(dispatch_queue_t!, () -> _)' 
                           dispatch_async(dispatch_get_main_queue()) {                                     
                                cell.image.image = self.imageArray.append( image )
                            }

                        }

                    }
                })
            }
        }
        else{

            println("Error in retrieving \(error)")

        }
    }

    return cell
}

Hope you people understand that code.

1 Answer 1

1

The proper way to use that dispatch block is like so:

dispatch_async(dispatch_get_main_queue(), { () -> Void in
                //perform your work here
                self.imageArray.append(image)
                cell.image.image = imageArray[indexPath.row]
            })

Another reason that the compiler is giving this warning is because you're trying to append images to an array and set that as the cells image. What you should be doing is shown above.

Finally, I would recommend moving your queries out of cellForRowAtIndexPath: and into seperate methods as this is bad code design.

Edit: Rewrote method to provide examples of good code design...

var imageArray = [UIImage]()

func performLookupQuery() {
    var query = PFQuery(className: "ParseClass")
    query.findObjectsInBackgroundWithBlock {(objects: [AnyObject]?, error: NSError?)
        if error == nil {
            let imageObjects = objects as! [PFObject]
            for object in imageObjects {
                let thumbnail = object["columnInParse"] as! PFFile
                thumbnail.getDataInBackgroundWithBlock{(imageData: NSData?, error: NSError?)
                    if error == nil {
                        if let image = UIImage(data: imageData!) {
                            imageArray.append(image)
                            //now your imageArray has all the images in it that you're trying to display
                            //you may need to reload the TableView after this to get it to display the images

                        }
                    }
                }
            }
        }
        self.tableView.reloadData()
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
    cell.image.image = nil
    cell.image.image = imageArray[indexPath.row]
    return cell
}

I didn't add all the error checking in the query method like you should, I was just writing it to show what you would do. Now that you have this query method, you can call it in viewDidLoad and then the results will be available when you try to load your table.

override func viewDidLoad(animated: Bool) {
    super.viewDidLoad(animated)
    self.performLookupQuery()
}
Sign up to request clarification or add additional context in comments.

8 Comments

And it won't even work properly because you can't async return the cell
Right, hence the reccomendation to move his query code outside of this method, return it into an array of UIImage and then use that to set the cell's image.
@Daniel I edited my answer to give you an overview (incomplete as it doesn't implement your other methods and the rest of the tableView delegate methods, but hopefully this helps you understand.
Should i pots all the code here for better view from code?
No what I've given you is sufficient to fix the most glaring issue you have. In numberOfRowsInSection make sure you return image array.count
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.