我已经在我的Swift应用程序中设置了Parse后端,以便我有一个有绘画的课程和另一个有用户的课程。
我还有一个指向绘画和用户指针的课程,因此每个用户都可以对绘画进行评分:
在我的主表视图中,我想加载当前登录用户已评级的所有绘画。为此,我使用此代码:
var paintingArray: [AnyObject] = []
// Define the query that will provide the data for the table view
override func queryForTable() -> PFQuery {
//Find User Painting Relations to display
var relationQuery = PFQuery(className:"UserPaintingRelation")
relationQuery.whereKey("userID", equalTo:PFUser.currentUser()!)
relationQuery.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
// Do something with the found objects
if let objects = objects as? [PFObject] {
for object in objects {
println(object.objectId)
//Add the paintingID of the current object to array
var paintingObjectId: AnyObject? = object["paintingID"]!.objectId
var paintingObjectIdString:String = paintingObjectId as! String
self.paintingArray.append(paintingObjectIdString)
}
}
} else {
// Log details of the failure
println("Error: \(error!) \(error!.userInfo!)")
}
}
//Query that loads relevant Painting objects
var query = PFQuery(className: "Painting")
//Make sure only the objects that are referenced in the paintingArray are loaded
query.whereKey("objectId", containedIn: self.paintingArray)
return query
}
此代码不会引发任何错误。但是,在模拟器中,我的表视图显示为空。如果我使用正确的paintingID来过滤我的查询:
query.whereKey("objectId", equalTo:"yd62zCrXR7")
而不是:
query.whereKey("objectId", containedIn: self.paintingArray)
一个对象显示在表视图中。
这让我相信第二个查询是在数组填充正确的字符串之前执行的,这会导致表视图不加载任何对象。这个假设是否正确?如果是这样,无论如何我可以确保在第二次查询执行之前,paintingArray完成从relationQuery加载所有字符串吗?
非常感谢,非常感谢所有帮助!在Swift上还是很新的,所以无法真正理解错误。
答案 0 :(得分:0)
按照我的评论编辑了您的代码。在您的情况下,对userPaintingRelation的解析调用是后台线程将在后台执行,而绘图查询在执行后台查询之前执行。
var paintingArray: [AnyObject] = []
// Define the query that will provide the data for the table view
override func queryForTable() -> Void {
//Find User Painting Relations to display
var relationQuery = PFQuery(className:"UserPaintingRelation")
relationQuery.whereKey("userID", equalTo:PFUser.currentUser()!)
relationQuery.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
// Do something with the found objects
if let objects = objects as? [PFObject] {
for object in objects {
println(object.objectId)
//Add the paintingID of the current object to array
var paintingObjectId: AnyObject? = object["paintingID"]!.objectId
var paintingObjectIdString:String = paintingObjectId as! String
self.paintingArray.append(paintingObjectIdString)
}
//Query that loads relevant Painting objects
var query = PFQuery(className: "Painting")
//Make sure only the objects that are referenced in the paintingArray are loaded
query.whereKey("objectId", containedIn: self.paintingArray)
var: tableArray = query.findObjects() as [PFObject] //array for datasource of table
yourTableView.reloadData()
}
} else {
// Log details of the failure
println("Error: \(error!) \(error!.userInfo!)")
}
}
}
答案 1 :(得分:0)
我通过不使用relationQuery.finObjectsInBackgroundWithBlock {}
解决了这个问题,而是使用relationQuery.findObjects{}
,因为该操作不会在后台执行,这确保我的数组paintingArray将在第二个查询之前填充字符串被执行。
这是我最终得到的代码。无论如何都不完美,但它现在有效。
let emptyArray: [AnyObject] = []
var paintingArray: [AnyObject] = []
override func queryForTable() -> PFQuery {
//Find User Painting Relations to display
var relationQuery = PFQuery(className:"UserPaintingRelation")
relationQuery.whereKey("userID", equalTo:PFUser.currentUser()!)
var paintings = relationQuery.findObjects() as! [PFObject]
for painting in paintings {
var paintingObjectId: AnyObject? = painting["paintingID"]!.objectId
var paintingObjectIdString:String = paintingObjectId as! String
self.paintingArray.append(paintingObjectIdString)
}
var query = PFQuery(className: "Painting")
query.whereKey("objectId", containedIn: self.paintingArray)
//Empty array so that tableview reloads completely when table is reloaded
self.storeArray = self.emptyArray
return query
}