Search code examples
swiftcore-datanspredicate

NSPredicate CONTAINS but only when not empty


It seems that with NSPredicate(format: "name CONTAINS %@", name):

If name is not empty then it works ok.

But if name is empty then it doesn't fetch everything. Instead it fetches nothing.

Currently I have to create two separate NSPredicates to bypass this behavior, but it gets complicated very quickly when there are multiple string values to filter.

For instance:

if name.isNotEmpty {
    predicate = NSPredicate(format: "name CONTAINS %@ AND summary = %@", name, summary)
} else {
    predicate = NSPredicate(format: "summary = %@", summary)
}

And then use that predicate for fetch requests.

Another option I have tried is to simply fetch everything and then filter it using the string.contains() function.

However, I would like to avoid returning too many records from my fetch requests if possible.

Is there a better way to do this?


Solution

  • I also use NSCompoundPredicate as suggested by @Joakim Danielson in comments to handle that behavior:

    You jut need to isolate which needs to use AND/OR in case you use multiple logic:

    var predicates: [NSPredicate] = []
    
    predicate.append(defaultPredicate1)
    predicate.append(defaultPredicate2)
    ...
    if condition1 {
        predicate.append(conditionPredicate1)
    }
    if condition2 {
        predicate.append(conditionPredicate2)
    }
    ...
    
    let finalPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
    

    With your simple case:

    var predicates: [NSPredicate] = []
    
    predicates.append(NSPredicate(format: "summary = %@", summary))
    
    if name.isNotEmpty {
        predicate.append(NSPredicate(format: "name CONTAINS %@)", name))
    }
    
    let finalPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)