20
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

スピカ(ネイルブック💅)Advent Calendar 2015

Day 3

Realm の検索条件に QueryKit を使ってみる

Last updated at Posted at 2015-12-02

この記事は - スピカ Advent Calendar 2015 - 3日目の記事です。

弊社の サービス では Realm を絶賛使っていますが、その検索条件部分をより Swift っぽく書いてみようをテーマに投稿します。

はじめに

Realm では通常、以下の filter メソッドに文字列で条件を記述するのですが、タイポなどした場合は実行時に、はじめてエラーとして現れます。


public func filter(predicateFormat: String, _ args: AnyObject...) -> Results<T>

これでは折角のコンパイル言語としての Swift の魅力が半減してしまいます。
そこで今回は QueryKit というライブラリを組み合わせて、そういった部分を解消しようという試みになります。

QueryKit

QueryKit 自体は CoreData 向けのライブラリなのですが、CoreData, Realm どちらも NSPredicate を利用したインターフェースになっているため、 Realm でも利用することが出来ます。

QueryKit を用いると NSPredicate が以下のような構文で表現されます。

// Name is equal to Kyle
name == "Kyle"
>
// Name is either equal to Kyle or Katie
name << ["Kyle", "Katie"]
>
// Age is equal to 27
age == 27
>
// Age is more than or equal to 25
age >= 25
>
// Age is within the range 22 to 30.
age << (22...30)

具体例

定義部分

以下のように RealmSwift.Object を普通に継承したクラスに対して、必要に応じて Arrtibute< AttributeType> 型のクラス変数を定義します。


import RealmSwift

class Dog: Object {
    dynamic var name = ""
    dynamic var age = 0
}
class Person: Object {
    dynamic var name = ""
}


import QueryKit

extension Dog {
    static var name: Attribute<String> { return Attribute("name") }
    static var age: Attribute<Int> { return Attribute("age") }
}

extension Person {
    static var name: Attribute<String> { return Attribute("name") }
}

クエリ部分

Realm からオブジェクトを取り出す際は、以下のように記述することが出来ます。

let realm = try! Realm()

// "name = %@", "Taro"
realm.objects(Dog).filter(Dog.name == "Taro")

// "name IN %@", ["Taro", "Jiro"]
realm.objects(Dog).filter(Dog.name << ["Taro", "Jiro"])

// "name = %@ AND age > %@", "Taro", 2
realm.objects(Dog).filter(Dog.name == "Taro" && Dog.age > 2)

メリット

  • 文字列ではないので、入力補完が働く ✨
  • Generics を用いて型の一致も判断されるので、以下のような式はコンパイル時にエラーとなる ✨
realm.objects(Dog).filter(Dog.age > "2")

// Binary operator '>' cannot be applied to operands of type 'Attribute<Int>' and 'String'

おわりに

駆け足でしたが、 Realm に QueryKit を組み合わせた例を紹介してみました 😎

 

20
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?