3

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.

4
  • At the top you have relatedContactObjects as an NSArray, why are you casting it to [AnyObject] ? Commented Aug 25, 2015 at 15:19
  • Xcode requires that it be cast to [AnyObject], but actually I don't think that is the problem. Please see my updated question. Commented Aug 25, 2015 at 15:28
  • Don't think that method supports that kind of thing. You might want to try containedIn This question may help. Commented Aug 25, 2015 at 15:29
  • Thanks, but that constraint is used to identify objects that are contained in a given array. I am trying to identify arrays that contain a given object. Commented Aug 25, 2015 at 15:46

2 Answers 2

4

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)
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for pointing that out. I thought equalTo was more literal. And just to complete your answer, here is the countObjects query I used: relatedContactQuery.countObjectsInBackgroundWithBlock{(count, error) -> Void in if (error == nil) { self.dealsPointingToContactCount = Int(count) }
Glad it helped. Fyi: Parse.com disuades count queries. Depending on the count, a resource saving alternative might be a cloud function that does a find() and then answers the length of the found collection.
Good to know. I'm running the query in the local datastore and the expected count is less than 100, so this should be okay for my situation.
0

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)")
                    }
                }
            }  
        } 
    }
}

3 Comments

I think you can do it the way you were first attempting. This way is okay, but consider that it will retrieve (using network resource and client memory) potentially many more objects than are needed. There's also the matter of expending compute effort on the local test. To get what you want via query, please clarify: objects where EVERY related contacts is in relatedContactObjects. Also, please indicate the type of the relatedContacts column.... an array of what?
The relatedContacts column is an array of pointers to Contact objects. For the query, relatedContactObjects is an array with only one object because containsAllObjectsInArray needs an NSArray. I really just want a count of the Deal objects where relatedContacts contains self.contactObject.
That makes your goal very easy to achieve.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.