RGM-79FP GM Striker RGM-79FP GM Striker - 2 months ago 20
iOS Question

Unable to populate to UITableView Swift

I tried to see if I was missing some strip of code, but maybe I don't see the error

Everything else is connected and set properly. But I can't see why I can't populate the UITableView

But I am unsure about why it is not passing on the data. Ideas?

func getLocalComments(point:PFGeoPoint){
var temp = [CommentDetails]()
DispatchQueue.global(qos: .background).async {
let qComments = PFQuery(className: "UserCommentary")
let qDrinks = PFQuery(className: "venueDrinks")
if self.type == "House Parties"{
//Query the bars
qDrinks.whereKey("venueName", equalTo: self.id)
qDrinks.whereKey("venueID", equalTo: self.venueName)
qDrinks.addDescendingOrder("createdAt")

qComments.whereKey("venueID", equalTo: self.id)
qComments.whereKey("venueName", equalTo: self.venueName)

do{
var comment:CommentDetails = CommentDetails.init(comm: "Test", ven: self.venueName, venId: self.id, owner: PFUser.current()!.username!, vote: 0)
let qReply1 = try qDrinks.findObjects()
if qReply1.count>0{
var i = 0
while i < 2 {
let item = qReply1[i]
print(item)
comment.cellType = 2
i+=1
}
//temp.append(comment)
}
comment = CommentDetails.init(comm: "Test", ven: self.venueName, venId: self.id, owner: PFUser.current()!.username!, vote: 0)
let qReply2 = try qComments.findObjects()
for item in qReply2{
comment.commentOwner = item.object(forKey: "owner") as! String
comment.comment = item.object(forKey: "comment") as! String
comment.isFile = item.object(forKey: "image") as! Bool
if comment.isFile {
let dataPhoto:PFFile = item.object(forKey: "imgFile") as! PFFile
let imageData:NSData = try dataPhoto.getData()
let image:UIImage = UIImage(data:imageData as Data)!
comment.imageFile = image
comment.cellType = 2
}
temp.append(comment)

}
print("Comment",temp)

}
catch{
print(error)
}
}
}
DispatchQueue.main.async {
print(temp)
self.commentList.removeAll()
self.commentList = temp
print("Comment",self.commentList)
self.commentTableView.reloadData()

}

}

Answer

You need to come back to the main thread at the end of the background thread. Check when to call the DispatchQueue.main.async method.

    func getLocalComments(point:PFGeoPoint){
        var temp = [CommentDetails]()
        DispatchQueue.global(qos: .background).async {
            let qComments = PFQuery(className: "UserCommentary")
            let qDrinks = PFQuery(className: "venueDrinks")
            if self.type == "House Parties"{
                //Query the bars
                qDrinks.whereKey("venueName", equalTo: self.id)
                qDrinks.whereKey("venueID", equalTo: self.venueName)
                qDrinks.addDescendingOrder("createdAt")

                qComments.whereKey("venueID", equalTo: self.id)
                qComments.whereKey("venueName", equalTo: self.venueName)

                do{
                    var comment:CommentDetails = CommentDetails.init(comm: "Test", ven: self.venueName, venId: self.id, owner: PFUser.current()!.username!, vote: 0)
                    let qReply1 = try qDrinks.findObjects()
                    if qReply1.count>0{
                        var i = 0
                        while i < 2 {
                            let item = qReply1[i]
                            print(item)
                            comment.cellType = 2
                            i+=1
                        }
                        //temp.append(comment)
                    }
                    comment = CommentDetails.init(comm: "Test", ven: self.venueName, venId: self.id, owner: PFUser.current()!.username!, vote: 0)
                    let qReply2 = try qComments.findObjects()
                    for item in qReply2{
                        comment.commentOwner = item.object(forKey: "owner") as! String
                        comment.comment = item.object(forKey: "comment") as! String
                        comment.isFile = item.object(forKey: "image") as! Bool
                        if comment.isFile {
                            let dataPhoto:PFFile = item.object(forKey: "imgFile") as! PFFile
                            let imageData:NSData = try dataPhoto.getData()
                            let image:UIImage = UIImage(data:imageData as Data)!
                            comment.imageFile = image
                            comment.cellType = 2
                        }
                        temp.append(comment)

                    }
                    print("Comment",temp)
                    DispatchQueue.main.async {
                        print(temp)
                        self.commentList.removeAll()
                        self.commentList = temp
                        print("Comment",self.commentList)
                        self.commentTableView.reloadData()

                    }
                }
                catch{
                    print(error)
                }
            }
        }
    }

Ok, so what happened? You know when you make the asynchronous background thread it is executed alongside the main thread. So If you set the break points inside the background thread and main thread you will notice that the main thread may starts first.

In your case DispatchQueue.main.async is executed before the background thread populates the temp array. When you move the block to inside of the DispatchQueue.global(qos: .background).async block, it will be executed in the main thread when it is needed.

In a short sentence, it is not executed form the top to bottom!