Swift CoreData 複数のpredicate条件の指定とIN句の書き方


概要

CoreDataのpredicateに複数条件の指定を行う。

ユーザの入力等によって動的に条件を生成する場合に使用する。


実装

NSCompoundPredicate(andPredicateWithSubpredicates: [NSPredicate])をpredicateに渡すことで複数の条件を渡すことができる。andPredicateWithSubpredicatesはandで繋ぐことだと思う。orPredicateWithSubpredicatesもある。

またIN検索はpredicateに

let status = ["new", "close"]
NSPredicate(format: "self.status IN %@", status)

のように記述して指定できる。


実装例はこんな感じ。

let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Entity")
var datePredicate:NSPredicate =  NSPredicate(format: "1 = 1")
//dateの入力がある場合、指定日を検索
if let argDate = date {            
   datePredicate = NSPredicate(format: "self.date BETWEEN {%@ , %@}", argDate as NSDate, NSDate(timeInterval: 24*60*60-1, since: argDate))
//statusの入力がある場合、指定statusをIN検索
var statusPredicate = NSPredicate(format: "1 = 1")
if let status = status {
    statusPredicate = NSPredicate(format: "self.status IN %@", status)
}
//複数predicateを渡す
fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [datePredicate, statusPredicate])

//do fetch ...

こういったWhere句SQLが生成される。

WHERE (( t0.ZDATE BETWEEN ? AND ?) AND  t0.ZSTATUS IN  (?,?) )


もちろんpredicateを一括りにして、

NSPredicate(format: "1 = 1 and self.column = %@ and self.status = %@ or self.title = %@, val1, val2, val3)

のように記述することもできるので、見通しの良い方を選択すればよい。