2018/02/03

【永久保存版】RealmSwiftの使い方 – Swift4.0

ちょっとずつ更新中。
長いので、目次からか、ブラウザの文字検索が無難。

Realmのインスタンスを取得

モデル定義

//モデル定義
import RealmSwift

class Person: Object { //人クラス
    @objc dynamic var name = ""
    @objc dynamic var age = 0
    @objc dynamic var dog: Dog? //Dogモデルと1対1の関係
    let cats = List<Cat>() //Catモデルと1対多の関連
}

class Animal: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0
}

class Dog: Animal { //Animalクラスを継承
}

class Cat: Animal { //Animalクラスを継承
}

コードの説明

let realm = try Realm()でインスタンスを取得するのが重要
ただ取得しただけ

import UIKit
import RealmSwift

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Realmのインスタンス取得
        do {
            let realm = try Realm()
            //データベースの操作の処理を書く            
        } catch {
            print("エラーだよ")
        }
    }
}

モデルオブジェクトを生成して、各プロパティに値を設定

モデル定義

一個上と同じ

コードの説明

let dog = Dog()でオブジェクトの生成するとオブジェクトに値を設定して初期化することが可能
ただこれは値を設定しただけなので、データベースに保存(永続化)されていない。

各プロパティへの値の設定方法は辞書と配列で初期化することも可能

辞書:let dog(value: [“name”:”Momo”],”age”:9)]
配列:let dog(value: [“Momo”,9])
*配列の場合には、全てのプロパティの値を含み、且つモデル内の定義と同じ順序でなければ不可。

import UIKit
import RealmSwift

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Realmのインスタンス取得
        do {
            let realm = try Realm()
            let dog = Dog()  //Dogモデルオブジェクトの生成
            
            //生成後に各プロパティに値を設定する
            dog.name = "Momo"
            dog.age = 9
            
        } catch {
            print("エラーだよ")
        }
    }
}

データベースへの書き込み(write, add)

モデル定義(記載有り)

//モデルの定義
import RealmSwift

class Person: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0
    @objc dynamic var mood = "Normal"
    @objc dynamic var dog: Dog? //Dogモデルと1対1の関係
    let cats = List<Cat>() //Catモデルと1対多の関連
}

class Animal: Object {

    @objc dynamic var name = ""
    @objc dynamic var age = 0
}

class Dog: Animal { //Animalクラスを継承
    let persons = LinkingObjects(fromType: Person.self, property: "dog") //Personへの逆方向の関連
}

class Cat: Animal { //Animalクラスを継承
    let persons = LinkingObjects(fromType: Person.self, property: "cats") //Personへの逆方向の関連
}

class UniqueObject: Object {
    @objc dynamic var id = 0
    @objc dynamic var value = ""
    @objc dynamic var optionalValue: String?
    override static func primaryKey() -> String? {
        return "id" //idプロパティをプライマリーキーに指定
    }
}

コードの説明

「try! realm.write」内に「realm.add(person)」で追加完了

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        //Realmのインスタンス取得
        do {
            let realm = try Realm()
            
            let person = Person() //Personモデルのオブジェクトを取得
            person.name = "Yu"
            person.age = 32
            
            try! realm.write {
                realm.add(person)
                print("成功だよ", person)
            }
            
        } catch {
            print("エラーだよ")
        }
    }
}

デバッグエリアの出力内容

print(“成功だよ”, person)の内容です。
*printはカンマ区切りで複数指定できる

成功だよ Person {
	name = Yu;
	age = 32;
	mood = Normal;
	dog = (null);
	cats = RLMArray<Cat> <0x1c0119980> (
	
	);
}

データベースへの書き込み(複数オブジェクト)

モデル定義

一個上と同じ

コードの説明

addはコレクション(配列や辞書的なこと)として渡すことで、まとめて追加することも可能

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        //Realmのインスタンス取得
        do {
            let realm = try Realm()
            
            let cats = [Cat(value: ["name": "Toto", "age": 1]), Cat(value: ["name": "Rao", "age": 2])]
            
            try! realm.write {
                realm.add(cats)
                print("成功だよ", cats)
            }
            
        } catch {
            print("エラーだよ")
        }
    }
}

デバッグエリアの出力内容

成功だよ [Cat {
	name = Toto;
	age = 1;
}, Cat {
	name = Rao;
	age = 2;
}]

データベースへの追加(関連するオブジェクトも一緒に)

モデル定義

一個上と同じ

コードの説明

追加は、そのモデルオブジェクトが持つ関連(1対1,1対多)も一緒に追加される

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        //Realmのインスタンス取得
        do {
            let realm = try Realm()
            
            let dictionary: [String: Any] =
                ["name": "Yu",
                 "age": 32,
                 "dog": ["name": "Momo", "age": 9],
                 "cats":[["name": "Toto", "age":1],["name": "Rao", "age": 2]]
                ]
            let person = Person(value: dictionary)
            
            //Personが持つ1対1の関連(dog)と1対多の関連(cats)も追加される
            
            try! realm.write {
                realm.add(person)
                print("成功だよ", person)
            }
            
        } catch {
            print("エラーだよ")
        }
    }
}

デバッグエリアの出力内容

PersonとCat(=cats)は1対多の関連がある。
また、ListはコレクションクラスでArrayとよく似た性質を持っているので、[0],[1]というように、順番が保持できる。

成功だよ Person {
	name = Yu;
	age = 32;
	mood = Normal;
	dog = Dog {
		name = Momo;
		age = 9;
	};
	cats = RLMArray&lt;Cat&gt; &lt;0x1c0306150&gt; (
		[0] Cat {
			name = Toto;
			age = 1;
		},
		[1] Cat {
			name = Rao;
			age = 2;
		}
	);
}

モデルオブジェクトの更新

モデル定義

一個上と同じ

コードの説明

データベースに保存したモデルオブジェクトのプロパティの値を更新すると新しい値がデータベースに反映される。
当然だが、プロパティの値を更新するのみなので、realm.addは使わない。
・アンマネージドオブジェクト:Realmに保存する前のもの
・マネージドオブジェクト:Realmに保存済みのもの

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        let person = Person(value: ["name": "Yu", "age": 32])
        /*
         この時点のpersonはRealmに書き込まれていないのでアンマネージドオブジェクト
        */
        person.mood = "Happy" //書き込まれていないので、realm.write内でなくてもプロパティの更新は問題なし
        
        do {
            let realm = try Realm()
            try! realm.write {
            realm.add(person) //PersonをRealmに保存したことで、マネージドオブジェクトになる
            print("1回目成功だよ", person)
            }
        } catch {
            print("エラーだよ")
        }
        /*
         この時点のPersonはマネージドオブジェクトなので、プロパティの更新はrealm.write内のみ可能
         */
        //person.mood = "sad" //×これだと実行不可
        do {
            let realm = try Realm()
            try! realm.write {
                person.mood = "Sad" //プロパティの更新
                print("2回目成功だよ", person)
            }
            
        } catch {
            print("エラーだよ")
        }
    }
}

デバッグエリアの出力内容

プロパティを変更したので、1回目と2回目でmoodの値が変更している

1回目成功だよ Person {
	name = Yu;
	age = 32;
	mood = Happy;
	dog = (null);
	cats = RLMArray<Cat> <0x1c0109630> (
	
	);
}
2回目成功だよ Person {
	name = Yu;
	age = 32;
	mood = Sad;
	dog = (null);
	cats = RLMArray<Cat> <0x1c01096c0> (
	
	);
}

1対多関連の追加と削除(List,append,remove)

モデル定義

一個上と同じ

コードの説明

Listクラスには配列や辞書と似たコレクションクラスなので、使い方も結構似てます。

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        let person = Person(value: ["name": "Yu", "age": 32])
        
        do {
            let realm = try Realm()
            try! realm.write {
                realm.add(person) //モデルオブジェクトの追加
                print("1回目成功だよ", person)
            }
        } catch {
            print("エラーだよ")
        }
        
        let cat = Cat(value: ["name": "Toto", "age": 1])
        
        /*
         1対多を追加
         */
        do {
            let realm = try Realm()
            try! realm.write {
                person.cats.append(cat) //1対多の関連を追加
                print("追加後person.cats: \(person.cats)") //catが含まれていることを確認
            }
        } catch {
        }
        /*
         1対多を削除
         */
        do {
            let realm = try Realm()
            try! realm.write {
                person.cats.remove(at: 0) //1対多の関連を削除
                print("削除後person.cats: \(person.cats)") //catが含まれていないことを確認
            }
        } catch {
            
        }
        //person.catsからcatが取り除かれるだけなので、catモデルは削除されていない。
        print("cat.isInvalidated: \(cat.isInvalidated)") //false
        
    }
}

デバッグエリアの出力内容

要素を取り除いた場合は、あくまでList内から取り除かれるだけで、取り除いたモデルオブジェクトはデータベースから削除されない。

1回目成功だよ Person {
	name = Yu;
	age = 32;
	mood = Normal;
	dog = (null);
	cats = RLMArray<Cat> <0x1c01193e0> (
	
	);
}
追加後person.cats: List<Cat> <0x1c0119350> (
	[0] Cat {ß
		name = Toto;
		age = 1;
	}
)
削除後person.cats: List<Cat> <0x1c0119350> (

)
cat.isInvalidated: false

モデルオブジェクトの更新(キー値コーディング)setValue(_:forKey:)

モデル定義

一個上と同じ

コードの説明

先ほどの「モデルオブジェクトの更新」とやろうとしていることは変わらないです。
・setValue(_:forKey:)で値を更新
・ListはsetValue(_:forKeyPath:)で値を更新?(多分)

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        let person = Person(value: ["name": "Yu",
                                    "age": 32,
                                    "dog": ["name": "Momo", "age": 9]])
        
        do {
            let realm = try Realm() //Realmのインスタンスを取得
            try! realm.write {
                realm.add(person) //モデルオブジェクトの追加
                print("1回目成功だよ", person)
            }
        } catch {
            print("エラーだよ")
        }
        /*
         setValue(_:forKey:)で値を更新
        */
        do {
            let realm = try Realm()
            try! realm.write {
                person.setValue("Happy", forKey: "mood")
                print("2回目成功だよ", person)
            }
        } catch {
        }
        /*
         setValue(_:forKeyPath:)で値を更新
        */
        do {
            let realm = try Realm()
            try! realm.write {
                person.setValue("10", forKeyPath: "dog.age")
                print("3回目成功だよ", person)
            }
        } catch {
        }
    }
}

デバッグエリアの出力内容

2回目だと、person.moodが更新。
3回目だと、person.dog.ageが更新。

1回目成功だよ Person {
	name = Yu;
	age = 32;
	mood = Normal;
	dog = Dog {
		name = Momo;
		age = 9;
	};
	cats = RLMArray<Cat> <0x1c011a700> (
	
	);
}
2回目成功だよ Person {
	name = Yu;
	age = 32;
	mood = Happy;
	dog = Dog {
		name = Momo;
		age = 9;
	};
	cats = RLMArray<Cat> <0x1c011a8b0> (
	
	);
}
3回目成功だよ Person {
	name = Yu;
	age = 32;
	mood = Happy;
	dog = Dog {
		name = Momo;
		age = 10;
	};
	cats = RLMArray<Cat> <0x1c011a940> (
	
	);
}

コレクションクラス(List,Result)の一括更新(キー値コーディング)

モデル定義

一個上と同じ

コードの説明

コレクションクラスであるListクラスとResultクラスはキー値コーディングに準拠しており、全て一括して更新可能。

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        let person = Person(value: ["name": "Yu",
                                    "age": 32,
                                    "cats": [["name": "Toto", "age": 1], ["name": "Rao", "age": 2]]])
        
        do {
            let realm = try Realm() //Realmのインスタンスを取得
            try! realm.write {
                realm.add(person) //モデルオブジェクトの追加
                print("1回目成功だよ", person)
            }
        } catch {
            print("エラーだよ")
        }
        /*
         setValue(_:forKeyPath:)で値を一括更新
        */
        do {
            let realm = try Realm()
            try! realm.write {
                person.setValue("10", forKeyPath: "cats.age")
                print("2回目成功だよ", person)
            }
        } catch {
        }
    }
}

デバッグエリアの出力内容

person.cats.ageがそれぞれ更新されている。

1回目成功だよ Person {
	name = Yu;
	age = 32;
	mood = Normal;
	dog = (null);
	cats = RLMArray<Cat> <0x1c0114fd0> (
		[0] Cat {
			name = Toto;
			age = 1;
		},
		[1] Cat {
			name = Rao;
			age = 2;
		}
	);
}
2回目成功だよ Person {
	name = Yu;
	age = 32;
	mood = Normal;
	dog = (null);
	cats = RLMArray<Cat> <0x1c4110bc0> (
		[0] Cat {
			name = Toto;
			age = 10;
		},
		[1] Cat {
			name = Rao;
			age = 10;
		}
	);
}

モデルオブジェクトの削除(delete)

モデル定義

一個上と同じ

コードの説明

Realmデータベースからモデルオブジェクトを削除するにはdelete(_:)、deleteAll()を使用。
削除後のモデルオブジェクトは無効になり、モデル定義したプロパティにアクセスするとクラッシュする

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        let object = UniqueObject(value: ["id": 10, "value": "abc"])
        do {
            let realm = try Realm() //Realmのインスタンスを取得
            try! realm.write {
                realm.add(object) //モデルオブジェクトの追加
                print("1回目成功だよ", object)
            }
        } catch {
            print("エラーだよ")
        }
        /*
         モデルオブジェクトの削除
        */
        do {
            let realm = try Realm()
            try! realm.write {
                realm.delete(object)
                print("2回目成功だよ", object)
                print("object.isInvalidated: \(object.isInvalidated)")
                
            }
        } catch {
        }
        /*
         削除され無効になったモデルオブジェクト)(isInvalidated)はプロバティにアクセスできなくなる
         */
        //print(object.id) //実行するとクラッシュ
    }
}

デバッグエリアの出力内容

1回目成功だよ UniqueObject {
	id = 10;
	value = abc;
	optionalValue = (null);
}
2回目成功だよ [invalid object]
object.isInvalidated: true

複数のモデルオブジェクトを一度に削除

モデル定義

一個上と同じ

コードの説明

複数のモデルオブジェクトを一度に削除したい場合には、delete(_:)にコレクションクラス(配列、List、Results、LinkingObjectなど)を渡します。

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        let cat1 = Cat(value: ["name": "Toto", "age": 1])
        let cat2 = Cat(value: ["name": "Rao", "age": 2])
        let person = Person(value: ["name": "Yu",
                                    "age": 32,
                                    "cats":[cat1, cat2]])
        do {
            let realm = try Realm() //Realmのインスタンスを取得
            try! realm.write {
                realm.add(person) //モデルオブジェクトの追加
                print("1回目成功だよ", person)
                print("cat1.isInvalidated: \(cat1.isInvalidated)")
                print("cat2.isInvalidated: \(cat2.isInvalidated)")
            }
        } catch {
            print("エラーだよ")
        }
        /*
         モデルオブジェクトの複数削除
        */
        do {
            let realm = try Realm()
            try! realm.write {
                realm.delete(person.cats) //モデルオブジェクトの複数削除
                print("2回目成功だよ", person)
                print("cat1.isInvalidated: \(cat1.isInvalidated)")
                print("cat2.isInvalidated: \(cat2.isInvalidated)")
            }
        } catch {
        }
    }
}

デバッグエリアの出力内容

Listであるcatsが削除されています。

1回目成功だよ Person {
	name = Yu;
	age = 32;
	mood = Normal;
	dog = (null);
	cats = RLMArray<Cat> <0x1c4109f30> (
		[0] Cat {
			name = Toto;
			age = 1;
		},
		[1] Cat {
			name = Rao;
			age = 2;
		}
	);
}
cat1.isInvalidated: false
cat2.isInvalidated: false
2回目成功だよ Person {
	name = Yu;
	age = 32;
	mood = Normal;
	dog = (null);
	cats = RLMArray<Cat> <0x1c0104890> (
	
	);
}
cat1.isInvalidated: true
cat2.isInvalidated: true

全てのモデルオブジェクトを削除(deleteAll)

モデル定義

一個上と同じ

コードの説明

deleteAll()を使用すると、全て削除可能

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        let dog = Dog(value: ["name": "Momo", "age": 9])
        let cat1 = Cat(value: ["name": "Toto", "age": 1])
        let cat2 = Cat(value: ["name": "Rao", "age": 2])
        let person = Person(value: ["name": "Yu",
                                    "age": 32,
                                    "dog": dog,
                                    "cats":[cat1, cat2]])
        let object = UniqueObject(value: ["id": 10, "value": "abc"])
        
        do {
            let realm = try Realm() //Realmのインスタンスを取得
            try! realm.write {
                realm.add([person, object]) //モデルオブジェクトの追加
                print("1回目成功だよ", person, object)
            }
        } catch {
            print("エラーだよ")
        }
        /*
         全てのモデルオブジェクトを一括削除
        */
        do {
            let realm = try Realm()
            try! realm.write {
                realm.deleteAll() //全てのモデルオブジェクトを削除
                print("2回目成功だよ", person, object)
                print("dog.isInvalidated: \(dog.isInvalidated)")
                print("cat1.isInvalidated: \(cat1.isInvalidated)")
                print("cat2.isInvalidated: \(cat2.isInvalidated)")
                print("person.isInvalidated: \(person.isInvalidated)")
                print("object.isInvalidated: \(object.isInvalidated)")
            }
        } catch {
        }
    }
}

デバッグエリアの出力内容

1回目成功だよ Person {
	name = Yu;
	age = 32;
	mood = Normal;
	dog = Dog {
		name = Momo;
		age = 9;
	};
	cats = RLMArray<Cat> <0x1c4116530> (
		[0] Cat {
			name = Toto;
			age = 1;
		},
		[1] Cat {
			name = Rao;
			age = 2;
		}
	);
} UniqueObject {
	id = 10;
	value = abc;
	optionalValue = (null);
}
2回目成功だよ [invalid object] [invalid object]
dog.isInvalidated: true
cat1.isInvalidated: true
cat2.isInvalidated: true
person.isInvalidated: true
object.isInvalidated: true

モデルオブジェクトの取得(Results)

モデル定義(記載あり)

//モデルオブジェクト
import RealmSwift

class Person: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0
    @objc dynamic var countryCode = ""
    @objc dynamic var dog: Dog? //Dogモデルと1対1の関係
    let cats = List<Cat>() //Catモデルと1対多の関連
}

class Animal: Object {

    @objc dynamic var name = ""
    @objc dynamic var age = 0
}

class Dog: Animal { //Animalクラスを継承
    let persons = LinkingObjects(fromType: Person.self, property: "dog") //Personへの逆方向の関連
}

class Cat: Animal { //Animalクラスを継承
    let persons = LinkingObjects(fromType: Person.self, property: "cats") //Personへの逆方向の関連
}

class UniqueObject: Object {
    @objc dynamic var id = 0
    override static func primaryKey() -> String? {
        return "id" //idプロパティをプライマリーキーに指定
    }
}

Resultsの説明

データベースに保存したモデルオブジェクトは、クエリ(検索条件)から取得可能。
クエリが実行されるとモデルオブジェクトを含むResultsクラスのインスタンスが返ってくる。
Resultsは読み取り専用のコレクションクラスですが、取得時に指定したクエリの実行結果が自動で反映される特殊なコレクションクラスで、直接Resultsクラス内の要素を編集する必要がない仕組み。
Resultsはコピーではなく、書き込みトランザクション(realm.write)を使って、Results内のデータを変更した場合には、データベースに反映される。

コードの説明

Realmデータベースに保存されている特定のモデルクラスのオブジェクトを全て取得するにはRealmクラスのobjects(_:)を使用。

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        do {
            let realm = try Realm()
            let results = realm.objects(Person.self)
            print("データベース追加前", results.count)
            print(results)
            
            try! realm.write {
                realm.add(Person())
                print("データベース追加後", results.count)
                print(results)
            }
            
        } catch {
            
        }
        /*
         resultsは「データベース内に保存してあるPersonモデルを全て取得する」というクエリの実行結果なので、データベースに1つPersonモデルが追加された結果が自動で反映される。
        */ 
    }
}

デバッグエリアの出力内容

データベース追加前と追加後で、オブジェクト数が0 -> 1になっています。

データベース追加前 0
Results<Person> <0x104423670> (

)
データベース追加後 1
Results<Person> <0x104423670> (
	[0] Person {
		name = ;
		age = 0;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c41193e0> (
		
		);
	}
)

ソート(並び替え)を行う(sorted)

モデル定義

一個上と同じ

コードの説明

1つまたは複数のプロパティの値を使ってソートすることが可能。
ソートは、(byKeyPath:ascending:)などを使用

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        //ageが異なる複数のPersonモデルを追加
        let person1 = Person(value: ["name": "B", "age": 20])
        let person2 = Person(value: ["name": "A", "age": 10])
        let person3 = Person(value: ["name": "C", "age": 30])
        
        do {
            let realm = try Realm() //Realmのインスタンスを取得
            try! realm.write {
                realm.add([person1, person2, person3])
                
                print("順不同で追加", person1, person2, person3)
                
            }
            
            //データベース内に保存してあるPersonモデルを全て取得します。
            var results = realm.objects(Person.self)
            
            //この時のresults内の要素の配列は不定です。
            print("順不同", results)
            
            //Personのageで昇順ソート(小さい順)
            results = results.sorted(byKeyPath: "age", ascending: true)
            //results内は、ageが10,20,30の順にソートされたPersonになります。
            print("ソート後", results)
            
            //ageが15のPersonモデルを追加
            try! realm.write {
                realm.add(Person(value: ["name": "D", "age": 15]))
                print("追加後", results)
                /*
                 resultsクエリは「データベース内にある全てのPersonモデルをageで昇順ソートする」
                 新たにPersonモデルが追加された結果は、resultsに自動で反映
                 PersonDも自動的に昇順のルールが当てはまる
                */
            }
        } catch {
            
        }
    }
}

デバッグエリアの出力内容

順不同で追加 Person {
	name = B;
	age = 20;
	countryCode = ;
	dog = (null);
	cats = RLMArray<Cat> <0x1c410cba0> (
	
	);
} Person {
	name = A;
	age = 10;
	countryCode = ;
	dog = (null);
	cats = RLMArray<Cat> <0x1c410cc30> (
	
	);
} Person {
	name = C;
	age = 30;
	countryCode = ;
	dog = (null);
	cats = RLMArray<Cat> <0x1c410ccc0> (
	
	);
}
順不同 Results<Person> <0x102113fe0> (
	[0] Person {
		name = B;
		age = 20;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c410d020> (
		
		);
	},
	[1] Person {
		name = A;
		age = 10;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c410d0b0> (
		
		);
	},
	[2] Person {
		name = C;
		age = 30;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c410d140> (
		
		);
	}
)
ソート後 Results<Person> <0x102033bb0> (
	[0] Person {
		name = A;
		age = 10;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c0107980> (
		
		);
	},
	[1] Person {
		name = B;
		age = 20;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c0107a10> (
		
		);
	},
	[2] Person {
		name = C;
		age = 30;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c0107aa0> (
		
		);
	}
)
追加後 Results<Person> <0x102033bb0> (
	[0] Person {
		name = A;
		age = 10;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c0107c50> (
		
		);
	},
	[1] Person {
		name = D;
		age = 15;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c410cf00> (
		
		);
	},
	[2] Person {
		name = B;
		age = 20;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c410cf90> (
		
		);
	},
	[3] Person {
		name = C;
		age = 30;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c0107ce0> (
		
		);
	}
)

検索条件でのコレクションの絞り込み(filer)

モデル定義

一個上と同じ

コードの説明

クエリの指定はfilter(_:_:)を使用する

import UIKit
import RealmSwift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func tappedButton(_ sender: Any) {
        
        //ageが異なる複数のPersonモデルを追加
        let person1 = Person(value: ["name": "A", "age": 20])
        let person2 = Person(value: ["name": "B", "age": 20, "countryCode": "jp"])
        let person3 = Person(value: ["name": "C", "age": 15, "countryCode": "jp"])
        
        do {
            let realm = try Realm() //Realmのインスタンスを取得
            try! realm.write {
                realm.add([person1, person2, person3])                
            }
            
            //データベース内に保存してあるPersonモデルを全て取得します。
            var results = realm.objects(Person.self)
            
            //この時のresults内の要素の配列は不定です。
            print("検索前", results)
            
            /*
             クエリ(検索条件)として、ageが18以上でcountryCodeが'jp'と一致するPersonモデル。
             条件内に一致するのはPersonBのみ
            */
            results = results.filter("age >= 18 && countryCode = 'jp'")
            print("検索後", results)
        } catch {
    
        }
    }
}

デバッグエリアの出力内容

検索前 Results<Person> <0x10bd16bd0> (
	[0] Person {
		name = A;
		age = 20;
		countryCode = ;
		dog = (null);
		cats = RLMArray<Cat> <0x1c41097e0> (
		
		);
	},
	[1] Person {
		name = B;
		age = 20;
		countryCode = jp;
		dog = (null);
		cats = RLMArray<Cat> <0x1c4109870> (
		
		);
	},
	[2] Person {
		name = C;
		age = 15;
		countryCode = jp;
		dog = (null);
		cats = RLMArray<Cat> <0x1c4109900> (
		
		);
	}
)
検索後 Results<Person> <0x10be2c410> (
	[0] Person {
		name = B;
		age = 20;
		countryCode = jp;
		dog = (null);
		cats = RLMArray<Cat> <0x1c010e100> (
		
		);
	}
)

お知らせ

ヒヨコ歩数計という歩きながらヒヨコが育っていくアプリを作って、いろんな方に結構使ってもらっています。
RealmSwift, Admobの動画・インステ・バナー広告、UICollectionView、iOS-Charts、UITableViewを使用しているので、是非ご利用ください!