1

My data design allows one user to have many votes; and each single record can also have many votes. I'm struggling massively with referencing and searching for a specific element relying on these

enter image description here

In the master view controller, I've a fetch controller on the Record entity, and a single var user entity (ie. the device-user) that is inserted into the same managedContext.

Assuming this is OK, when preparing for segue to detailed view controller, I want to pass in the selected record (no problem); an array of all votes for that record (I think no problem, code below); and (here's the tricky part) the optional device-user's vote for that record (this is my question).

let votesAsSet = record.votes
controller.votes = votesAsSet?.allObjects as? [Vote]

let predicateForUsersVote = NSPredicate(format: "record.votes.user == user")
let thisUsersVoteForThisRecordAsSet = votesAsSet?.filteredSetUsingPredicate(predicateForUsersVote)                

controller.thisUsersVote = thisUsersVoteForThisRecordAsSet!.first as? Vote

What I'm trying to do is to iterate through the user's votes in core data for one where the record's user matches the device-user.

DrWhat
  • 2,360
  • 5
  • 19
  • 33

1 Answers1

1

Since your predicate is already operating on the set of Votes for the record, you can just use the user property directly. But you must substitute in the correct value for the device-user, eg:

let predicateForUsersVote = NSPredicate(format: "user == %@", device-user)

The result of applying this predicate to the set will also be a set, so I think you may need to use .anyObject() rather than .first to get the relevant Vote object.

pbasdf
  • 21,386
  • 4
  • 43
  • 75
  • My God it works!!! I've read a lot about predicates, NSSets and Core Data, and your answer brings it together nicely. One supplementary question if you've a moment: why not just "user == user" or "user == self.user", both of which seem to work? – DrWhat Jun 10 '16 at 15:12
  • Within a predicate, `user` refers to the `user` property **of the object being evaluated**: in this case, each `Vote` object from the set. Likewise `self` refers to the object itself. So both "user == user" and "user == self.user" compare the `user` property of the object with the `user` property of the object, and will both evaluate to true for all objects - not just the device-user. – pbasdf Jun 10 '16 at 15:23
  • If you want to compare with a value from the code where you build the predicate, you have to substitute the value in using the %@ format. – pbasdf Jun 10 '16 at 15:25