1
votes

Which predicate i need to use where objects in returned from Core Data array:

  1. First objects must match completely;
  2. Other object must just contained the specific word;

For example: I have entity Man(firstName:String, lastName: String). Let's say, i have this objects in Core Data: 1) Man(firstName: "John", secondName: "Alexandrov"), 2) Man(firstName: "Alex", secondName: "Kombarov"), 3) Man(firstName: "Felps", secondName: "Alexan").

And in returned arr i want to see [Man(firstName: "Alex", secondName: "Kombarov"), Man(firstName: "Felps", secondName: "Alexan"), Man(firstName: "John", secondName: "Alexandrov")]

How can i achieved this?

2
Do you want to filter the data, or to sort it? A predicate can only achieve the former.pbasdf
@pbasdf, do you mean that i can only get objects in random sequence, and i cant sort them to a specific sequence in fetch request? Dmitriy Greh
To sort the results when you fetch them, you must use NSSortDescriptor (not NSPredicate). But CoreData is very restrictive: a fetch request can only be sorted according to an attribute value (or an attribute of a to-one relationship). If you want a more complicated sort order, you will need to sort the array that is returned by the fetch request.pbasdf

2 Answers

3
votes

You could use a NSCompoundPredicate.

First, you'd create a predicate for the firstName. This one would be strict, so you'd search for matches using ==:

let firstNamePredicate = NSPredicate(format: "%K == %@", argumentArray: [#keyPath(Man.firstName), "alex"])

Then, you'd create a predicate for the lastName. This one is less strict, so you'd use CONTAINS:

let lastNamePredicate = NSPredicate(format: "%K CONTAINS[c] %@", argumentArray: [#keyPath(Man.lastName), "alex"])

Then you'd create an NSCompoundPredicate using the orPredicateWithSubpredicates signature.

let compoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [firstNamePredicate, lastNamePredicate])

From there, you could create a NSFetchRequest and assign compoundPredicate as the predicate for the fetchRequest.

If you want to sort the results, you can add one or more NSSortDescriptors to your NSFetchRequest:

let sortByLastName = NSSortDescriptor(key: #keyPath(Man.lastName), ascending: true)
let sortByFirstName = NSSortDescriptor(key: #keyPath(Man.firstName), ascending: true)
request.sortDescriptors = [sortByLastName, sortByFirstName]

Then, you'd do the fetch:

let request: NSFetchRequest = Man.fetchRequest()
request.predicate = compoundPredicate

var results: [Man] = []

do {
  results = try context.fetch(request)
} catch {
  print("Something went horribly wrong!")
}

Here's a link to a useful post on NSPredicate

0
votes

Adding to @Adrian answer, I had to make couple changes for it to work.

    let FIRSTNAME = "Alex"
    let LASTNAME = "Smith"
    let firstNamePredicate = NSPredicate(format: "firstName == %@", FIRSTNAME)
    let lastNamePredicate = NSPredicate(format: "firstName == %@", LASTNAME)
    let compoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [firstNamePredicate, lastNamePredicate])
    request.predicate = compoundPredicate
    do {
      results = try context.fetch(request)
    } catch {
      print("Something went horribly wrong!")
    }