【Swift Realm】NSPredicateクエリの構築方法と使い方!比較や置換
この記事からわかること
- Realm Swiftのfilterメソッドでの条件指定方法
- NSPredicateクエリの定義方法や使い方
- 使用できる比較演算子や論理演算子とは?
- 変数を組み込む方法
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
Realm Swiftで取得したデータをフィルタリングする際に必要になる「NSPredicateクエリ
」についてまとめていきます。
NSPredicateクエリとは?
SwiftのNSPredicate
とはRealmに限った話ではなくデータベースからデータを取得する際の条件を含んだクエリを構築できるクラスです。条件は主に文字列と比較演算子を組み合わせて定義できます。
クラスのイニシャライザを使用して条件をインスタンス化することができます。
let predicate = NSPredicate(format: "progressMinutes > 1 AND name == %@", "Ali")
ポイント
- プロパティ名をそのまま記述
- 比較演算子を使用
- 文字列で定義
- 変数の値を組み込むことも可能
- 入れ子になったテーブルにはドットシンタックスでアクセス
使用できる比較/論理演算子
- 等しい:== or =
- 等しくない:!= or <>
- より大きい:>
- より小さい:<
- 以上:>=
- 未満:<=
- 等しいまたは範囲内か:between
- 含まれるか:in
- AND:&&
- OR:||
- NOT:!
=
などは文字列、数値、日付などに対応していますが>
などは数値と日付のみに対応しており、文字列は比較できません。
Realmのfilterメソッドでの使い方
今回はRealmを使った場合で以下のようなテーブル定義があると仮定して条件の指定方法を見ていきます。filterメソッドではクロージャの中にそのままNSPredicateクエリとなる文字列を組み込みます。
class Shop: Object {
@Persisted var name = ""
@Persisted var employee = 0
}
特定の値にマッチするデータを取得する
単純に指定した値とマッチしたデータを取得するにはプロパティ名 比較演算子 値
の形式で記述します。値は文字列の場合は''
で囲い、数値の場合はそのまま指定できます。
let shopTable = realm.objects(Shop.self).filter("name == 'Chez Ame'")
let shopTable = realm.objects(Shop.self).filter("employee < 30")
プロパティ名には補完機能が動作しないため誤字脱字があると以下のようなエラーが発生してしまうので注意してください。
"Invalid keypath 'empoyee': Property 'empoyee' not found in object of type 'Shop'"
範囲内のデータを取得する
between
を使用することで数値や日付が範囲内にマッチするデータのみを取得することができます。
let shopTable = realm.objects(Shop.self).filter("employee between {10, 40}")
複数の条件を指定する
複数の条件を指定するには&&
や||
などの論理演算子を使用します。
let shopTable = realm.objects(Shop.self).filter("name contains 'Chez' && employee > 10")
文字列の比較
文字列の比較は比較演算子ではなく専用のオペレータを使用することで比較できます。
- 先頭を比較:beginsWith
- 含まれる:contains or in
- 末尾を比較:endsWith
- 一致(ワイルドカード使用可):like
これらのオペレータを使用する場合でも記述形式プロパティ名 オペレータ 値
に変更はありません。オペレータの右側に記述した値が先頭にあるかや含まれるかを検証できます。
let shopTable = realm.objects(Shop.self).filter("name like '*K*'")
変数の組み込み
条件に使用する値に変数に格納されている値や動的な計算結果を渡したい時は%@
を使用してプレースホルダーを設置し、置換する対象の値を2つ目以降の引数に渡します。
let shopName = "Chez Ame"
let shopTable = realm.objects(Shop.self).filter("name == %@",shopName)
複数の場合の例
let time = df.string(from: date)
scheduleArray = scheduleArray.filter("startDate == %@ OR endDate == %@",time,time)
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。