2018/02/03
【永久保存版】RealmSwiftの使い方 – Swift4.0
ちょっとずつ更新中。
長いので、目次からか、ブラウザの文字検索が無難。
目次
- Realmのインスタンスを取得
- モデルオブジェクトを生成して、各プロパティに値を設定
- データベースへの書き込み(write, add)
- データベースへの書き込み(複数オブジェクト)
- データベースへの追加(関連するオブジェクトも一緒に)
- モデルオブジェクトの更新
- 1対多関連の追加と削除(List,append,remove)
- モデルオブジェクトの更新(キー値コーディング)setValue(_:forKey:)
- コレクションクラス(List,Result)の一括更新(キー値コーディング)
- モデルオブジェクトの削除(delete)
- 複数のモデルオブジェクトを一度に削除
- 全てのモデルオブジェクトを削除(deleteAll)
- モデルオブジェクトの取得(Results)
- ソート(並び替え)を行う(sorted)
- 検索条件でのコレクションの絞り込み(filer)
Realmのインスタンスを取得
モデル定義
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
//モデル定義 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()でインスタンスを取得するのが重要
ただ取得しただけ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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])
*配列の場合には、全てのプロパティの値を含み、且つモデル内の定義と同じ順序でなければ不可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
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)
モデル定義(記載有り)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
//モデルの定義 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)」で追加完了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
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はカンマ区切りで複数指定できる
1 2 3 4 5 6 7 8 9 |
成功だよ Person { name = Yu; age = 32; mood = Normal; dog = (null); cats = RLMArray<Cat> <0x1c0119980> ( ); } |
データベースへの書き込み(複数オブジェクト)
モデル定義
一個上と同じ
コードの説明
addはコレクション(配列や辞書的なこと)として渡すことで、まとめて追加することも可能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
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("エラーだよ") } } } |
デバッグエリアの出力内容
1 2 3 4 5 6 7 |
成功だよ [Cat { name = Toto; age = 1; }, Cat { name = Rao; age = 2; }] |
データベースへの追加(関連するオブジェクトも一緒に)
モデル定義
一個上と同じ
コードの説明
追加は、そのモデルオブジェクトが持つ関連(1対1,1対多)も一緒に追加される
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
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]というように、順番が保持できる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
成功だよ Person { name = Yu; age = 32; mood = Normal; dog = Dog { name = Momo; age = 9; }; cats = RLMArray<Cat> <0x1c0306150> ( [0] Cat { name = Toto; age = 1; }, [1] Cat { name = Rao; age = 2; } ); } |
モデルオブジェクトの更新
モデル定義
一個上と同じ
コードの説明
データベースに保存したモデルオブジェクトのプロパティの値を更新すると新しい値がデータベースに反映される。
当然だが、プロパティの値を更新するのみなので、realm.addは使わない。
・アンマネージドオブジェクト:Realmに保存する前のもの
・マネージドオブジェクト:Realmに保存済みのもの
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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クラスには配列や辞書と似たコレクションクラスなので、使い方も結構似てます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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:)で値を更新?(多分)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
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クラスはキー値コーディングに準拠しており、全て一括して更新可能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
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()を使用。
削除後のモデルオブジェクトは無効になり、モデル定義したプロパティにアクセスするとクラッシュする
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
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 2 3 4 5 6 7 |
1回目成功だよ UniqueObject { id = 10; value = abc; optionalValue = (null); } 2回目成功だよ [invalid object] object.isInvalidated: true |
複数のモデルオブジェクトを一度に削除
モデル定義
一個上と同じ
コードの説明
複数のモデルオブジェクトを一度に削除したい場合には、delete(_:)にコレクションクラス(配列、List、Results、LinkingObjectなど)を渡します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
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()を使用すると、全て削除可能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
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)
モデル定義(記載あり)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
//モデルオブジェクト 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(_:)を使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
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になっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
データベース追加前 0 Results<Person> <0x104423670> ( ) データベース追加後 1 Results<Person> <0x104423670> ( [0] Person { name = ; age = 0; countryCode = ; dog = (null); cats = RLMArray<Cat> <0x1c41193e0> ( ); } ) |
ソート(並び替え)を行う(sorted)
モデル定義
一個上と同じ
コードの説明
1つまたは複数のプロパティの値を使ってソートすることが可能。
ソートは、(byKeyPath:ascending:)などを使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
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 { } } } |
デバッグエリアの出力内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
順不同で追加 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(_:_:)を使用する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
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 { } } } |
デバッグエリアの出力内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
検索前 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を使用しているので、是非ご利用ください!