blwinters
blwinters

Reputation: 2191

PFQuery where array of pointers contains a certain PFObject

Objects in my class Deal have an attribute relatedContacts which is an array of pointers to Contact objects. I'm running the following query to determine whether the current Contact object is the target of a pointer in any Deal, prior to deleting the Contact.

let relatedContactObjects:NSArray = [self.contactObject] as NSArray

let relatedContactQuery:PFQuery = PFQuery(className: "Deal")
    relatedContactQuery.fromLocalDatastore()
    relatedContactQuery.fromPinWithName("Deals")
    relatedContactQuery.whereKey("user", equalTo: PFUser.currentUser()!)
    relatedContactQuery.whereKey("relatedContacts", containsAllObjectsInArray: relatedContactObjects as [AnyObject])

However this returns Parse Error 102: "Value type not supported for $all queries."

The Parse documentation says that containsAllObjectsInArray takes an NSArray, but Xcode shows a warning that NSArray is not implicity convertible to [AnyObject].

Any ideas how I can make this query work?

Edit: I looked at the contents of relatedContacts and it seems that each instance contains an array of dictionaries, example: [{"__type":"Pointer","className":"Contact","objectId":"BoLym053hX"},{"__type":"Pointer","className":"Contact","objectId":"AgpnxAFUBn"},{"__type":"Pointer","className":"Contact","objectId":"ob20tThdfp"}]

As suggested, I've also looked at the containedIn query constraint, but that is used to identify objects that are contained in a given array. I am trying to identify arrays that contain a given object.

Upvotes: 3

Views: 609

Answers (2)

blwinters
blwinters

Reputation: 2191

Prior to the accepted answer, I also tried using loops to go through the arrays and identify whether they contained the current object, then incremented a count.

var dealsPointingToContactCount:Int = 0
func countDealsRelatedToContact() {
    let dealsWithRelatedContactQuery:PFQuery = PFQuery(className: "Deal")
    dealsWithRelatedContactQuery.fromLocalDatastore()
    dealsWithRelatedContactQuery.fromPinWithName("Deals")
    dealsWithRelatedContactQuery.whereKey("user", equalTo:PFUser.currentUser()!)
    dealsWithRelatedContactQuery.whereKeyExists("relatedContacts")
    dealsWithRelatedContactQuery.findObjectsInBackgroundWithBlock{(objects, error) -> Void in

        if (error == nil) {

            var dealsWithPointersToContacts:NSArray = objects! as NSArray

            for deal in dealsWithPointersToContacts {

                var dealContactsArray:NSArray = deal["relatedContacts"] as! [PFObject]

                for contact in dealContactsArray {
                    if contact as! PFObject == self.object {
                        self.dealsPointingToContactCount++
                        println("Deals pointing to current contact: \(self.dealsPointingToContactCount)")
                    }
                }
            }  
        } 
    }
}

Upvotes: 0

danh
danh

Reputation: 62686

Parse.com overloads equalTo: by allowing it to mean either: (a) a singular property equals the operand, or (b) an array property contains the operand. So you're objective is easily stated as follows:

relatedContactQuery.fromPinWithName("Deals")
relatedContactQuery.whereKey("user", equalTo: PFUser.currentUser()!)
relatedContactQuery.whereKey("relatedContacts", equalTo:self.contactObject)

Upvotes: 4

Related Questions