简体   繁体   English

使用其他解析查询的结果过滤解析查询不起作用-Swift

[英]Filter Parse query with results from other Parse query not working - Swift

I have set up my Parse backend in my Swift app so that I have a class with Paintings and another one with Users. 我已经在我的Swift应用程序中设置了我的Parse后端,所以我有一个关于Paintings的类,另一个是与Users的类。

I also have a class with pointers to both paintings and users, so that each user can rate paintings: 我还有一个类,它既包含绘画又包含指向用户的指针,以便每个用户都可以对绘画进行评分: 在此处输入图片说明

In my main table view I want to load all the paintings that the current logged in user has rated. 在我的主表视图中,我想加载当前登录用户已评级的所有绘画。 To do this I am using this code: 为此,我使用以下代码:

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
}

This code does not throw any errors. 此代码不会引发任何错误。 However, in the simulator my table view appears to be empty. 但是,在模拟器中,我的表格视图似乎是空的。 If I use a correct paintingID to filter my query: 如果我使用正确的paintingID来过滤查询:

query.whereKey("objectId", equalTo:"yd62zCrXR7")

instead of: 代替:

query.whereKey("objectId", containedIn: self.paintingArray)

one object shows up in the table view. 表格视图中会显示一个对象。

This leads me to believe that the second query is executed before the array has been filled with the correct strings, which results in the table view not loading any objects. 这使我相信第二个查询是在数组填充正确的字符串之前执行的,这导致表视图不加载任何对象。 Is this assumption correct? 这个假设正确吗? And if so, is there anyway I can make sure that the paintingArray finishes loading all the strings from the relationQuery before my second query executes? 如果是这样,无论如何,我可以确保在执行第二个查询之前,paintingArray完成了从RelationQuery加载所有字符串的工作吗?

Many thanks, all help is greatly appreciated! 非常感谢,非常感谢所有帮助! Still quite new at Swift so can't really wrap my head around what is wrong. 在Swift上还是很新的东西,所以我无法真正解决问题。

Edited your code as I commented. 我评论了您的代码。 In your case the parse call for userPaintingRelation is a background thread will be executed in background whereas the Paintings query executed before the background query is executed. 在您的情况下,对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!)")
    }

}
}

I solved this issue by not using relationQuery.finObjectsInBackgroundWithBlock {} but instead using relationQuery.findObjects{} as that operation will not be executed in the background, which makes sure that my array paintingArray will be filled with strings before the second query is executed. 我通过不使用relationQuery.finObjectsInBackgroundWithBlock {}解决了此问题,而是使用了relationQuery.findObjects{}因为该操作不会在后台执行,这可以确保在执行第二个查询之前,我的数组paintingArray将被字符串填充。

Here is the code I ended up with. 这是我最终得到的代码。 Not perfect by any means, but it works for now. 无论如何,它都不是完美的,但现在可以使用。

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM