swiftuitableviewpfquery

Swift why when Retrieving data from Parse I have to press button twice to load data in tableview


Below is my code that retrieves images from Parse server class and load it in a tableview. When I press GetAlbum UIbutton to show the data I have to press it twice to successfully have data displayed in the tableview and I can not know what's the reason. please help ( PS: I am new to swift)

var Saveddata: [UIImage] = []

@IBAction func getAlbum(_ sender: AnyObject) {
    if (self.textEntercode.text == "")
    {
        let alert = UIAlertController(title: "No Entered value", message:   "Please enter value", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil));
        //event handler with closure

        present(alert, animated: true, completion: nil);
    }
    else {
        //-------------Get Data from Parse Server-------------------
        var photo = textEntercode.text
        let query = PFQuery(className: "Photostable10")

        query.whereKey("photo", equalTo: photo)
        //query.whereKey("Score", greaterThan: 1000)

        query.findObjectsInBackground(block: { (objects : [PFObject]?, error: Error?) -> Void in
            if error == nil {
                for object in objects! {
                    if let userPicture = object.value(forKey: "photo") {
                        let userPicture = object.value(forKey: "photo")! as! PFFile
                        userPicture.getDataInBackground({ (imageData: Data?, error: Error?) -> Void in
                            let image = UIImage(data: imageData!)
                            if image != nil {
                                self.Saveddata.append(image!)
                            }
                        })
                    }
                }
            }
        })
        self.tableview.reloadData()
    } //else close
}

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell")!

    cell.textLabel!.text = "Post"
    cell.imageView?.image = Saveddata[indexPath.row]
    return cell

}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.Saveddata.count
}

Solution

  • Your call to self.tableView.reloadData() is in the wrong place and it's being called from the wrong queue. You need to call it on the main queue and it needs to be called inside the query completion handler after you update the data model.

    query.findObjectsInBackground(block: { (objects : [PFObject]?, error: Error?) -> Void in
        if error == nil {
            for object in objects! {
                if let userPicture = object.value(forKey: "photo") {
                    let userPicture = object.value(forKey: "photo")! as! PFFile
                    userPicture.getDataInBackground({ (imageData: Data?, error: Error?) -> Void in
                        let image = UIImage(data: imageData!)
                        if image != nil {
                            self.Saveddata.append(image!)
                        }
                    })
                }
            }
            DispatchQueue.main.async {
                self.tableview.reloadData()
            }
        }
    })