2

List item

So I'm trying to set up a request with multiple conditions in Swift. The SQL equivalent to:

select BOARDID
 from BOARD
 where BOARDID not like "someBoard"
 and BOARDID not like "anotherBoard"
 ..

I have an array of strings and I'm trying to iterate over each to create a subPredicate, add it to a compoundPredicate, then create a fetch request using that compoundPredicate:

let openBoards = ["someBoard", "anotherBoard", "etc"],
    request = NSFetchRequest(entityName: "Board")

var openBoardsSubPredicates: Array = [],
    error: NSError? = nil

for board in openBoards {
    var subPredicate = NSPredicate(format: "boardID not like '\(board)'")
    openBoardsSubPredicates += subPredicate
}

request.predicate = NSCompoundPredicate.andPredicateWithSubpredicates(openBoardsSubPredicates)

However, it fails at the var subPredicate line..

Thanks!

Pirijan
  • 3,430
  • 3
  • 19
  • 29
  • What do you mean it "fails"? Be more specific. Is it a compiler error? Is it crashing at runtime? What error is it reporting? – drewag Jul 26 '14 at 18:02
  • I get the following two errors: 1. An uncaught exception was raised, and 2. Unable to parse the format string "boardID not like 'someBoard'" – Pirijan Jul 26 '14 at 18:02

1 Answers1

1

The error tells you what the problem is. The format you are providing is not a valid format. Specifically, there is no "not like" comparison. You have to do the "not" outside:

NSPredicate(format: "not (boardID like %@)", board)

As @MartinR mentioned below, you can have NSPredicate automatically escape special characters so they don't interfere with the predicate by having it insert the variable instead of using string interpolation.

drewag
  • 93,393
  • 28
  • 139
  • 128
  • Thanks! I thought the format string correlated to sqlite syntax :( – Pirijan Jul 26 '14 at 18:19
  • 2
    Better: `NSPredicate(format: "not (boardID like %@)", board)`. Otherwise it crashes if "board" contains special characters like a single quote. One should never mix string formatting (or in this case, string interpolation) and predicate formatting. – Martin R Jul 26 '14 at 18:19
  • 1
    @Pirijan, you can get more information on NSPredicate format in [Apple's Documentation](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html) – drewag Jul 26 '14 at 18:23
  • @drewag: Minor nitpicking: `NSPredicate(format: ...)` does not "automatically escape special characters". A predicate is a tree-like structure (using the various subclasses of NSPredicate like NSComparisonPredicate, NSCompoundPredicate, ...) and not a string. `NSPredicate(format: ...)` is a convenience method to create a predicate from the format string and the arguments. If the format string contains keys or values then these have to be escaped correctly. If the keys and values are provided as arguments then there is no need to escape them. – Martin R Jul 26 '14 at 18:36
  • @MartinR, I'm not sure what your saying. According to the documentation "argList: The arguments to substitute into predicateFormat." – drewag Jul 26 '14 at 18:45
  • @drewag: I am expressing myself badly, and it is really not important at all. What I meant is: the *internal representation* of a predicate is not a string but a tree-like structure (see http://stackoverflow.com/a/19454321/1187415 for an example how it can be decomposed again). Therefore I found *"NSPredicate automatically escapes special characters"* slightly misleading. – Martin R Jul 26 '14 at 19:06
  • @MartinR, ok, I see what you are saying. But I believe that the format string is generated first (by inserting in the arguments) and then the internal representation is created. The entire "boardId like someBoard" creates a single sub predicate. – drewag Jul 26 '14 at 19:09
  • @drewag: I do not think so (an argument could be an entire array of objects) but of course I do not know. – Martin R Jul 26 '14 at 19:12
  • @MartinR Ok ya, I also cannot say for 100% certainty :) Thanks for the discussion though. – drewag Jul 26 '14 at 19:13