こんにちは。
1. Realm Swift の filter
は NSPredicate のシステムに即しているが……
それが故,filter は「テキスト」で記述されるためコンパイル時検証が弱い。
そこで,引数として keyPath を渡し,強固に型チェックまでさせる。
2. keyPath は key をもつ型と key 自体の型を判別できる
keyPath の型云々は以下を参照
型を使って,「keyをもつ型」と「key に対する value の型」を強固に制約させる
import Foundation import RealmSwift extension Results { final func filter(_ keyPath: ReferenceWritableKeyPath<Element, String>, value: String) -> Results<Element> { let name = NSExpression(forKeyPath: keyPath).keyPath return self.filter("%K=%@", name, value) } final func filter(_ keyPath: ReferenceWritableKeyPath<Element, Int32>, value: Int32) -> Results<Element> { let name = NSExpression(forKeyPath: keyPath).keyPath return self.filter("%K=%d", name, value) } final func filter(_ keyPath: ReferenceWritableKeyPath<Element, Int64>, value: Int64) -> Results<Element> { let name = NSExpression(forKeyPath: keyPath).keyPath return self.filter("%K=%lld", name, value) } final func filter(_ keyPath: ReferenceWritableKeyPath<Element, Int>, value: Int) -> Results<Element> { let name = NSExpression(forKeyPath: keyPath).keyPath #if arch(arm64) || arch(x86_64) return self.filter("%K=%lld", name, value) #else return self.filter("%K=%d", name, value) #endif } }
※ Swift の Int は 32-bit 環境では 32-bit,64-bit 環境では 64-bit である。iOS 10 対応して,iPhone 5 や iPhone 5c への対応を行うときに気をつけなければならない。
使用例
let account = realm .objects(AccountEntity.self) .filter(\.uuid, string: uuid) .first
対象の型の中にある key を強制的に選択させることで,プログラミングのミスを回避する。
オーバーヘッドがあるかどうかは知らない。まあ誤差程度でしょう
「.」で入力を始めると,サジェストされないのがつらいですが…… 改善してください……
おまけ
型が間違っているとコンパイルエラーとしてこんな感じに出る。