Realm SwiftのCRUD操作についてのまとめです。
ユーザーモデルを1つ用意し、そのユーザーの名前をレコードに追加、更新、削除、読み込みするものです。
レコードに保存したものはtableViewで確認できるようにし、1つの画面でさっと一連の流れを確認できるようにしています。
<h3> 実行環境 </h3>
Swift:4.1.2
Xcode:10.1
Realm:3.16.0
RealmSwift:3.16.0
<h3> RealmSwiftでのモデル </h3>
モデルクラスは、RealmSwiftが用意している、Objectクラスを継承して作ります。
Arrayはサポートされていないので、Listを使って保存するようですが、今回は簡単のため使わずに一連のCRUD操作とその確認を行います。
<h3>RealmSwiftでのCreate処理</h3>
1 2 3 4 5 6 7 8 9 |
let realm = try! Realm() let user = User() user.name = "名前" user.age = 1 user.time = 1.0 user.created_at = Date() try! realm.write { realm.add(user) } |
<h3>RealmSwiftでのRead処理</h3>
1 2 3 |
let realm = try! Realm() let allData = realm.objects(User.self) print("\(allData):Realmに保存した全てのUserレコード") |
<h3>RealmSwiftでのDelete処理</h3>
1 2 3 4 5 6 7 8 9 10 |
let realm = try! Realm() let toBeDeletedUserName = "削除するレコードに登録されたnameの値" print("\(toBeDeletedUserName!):削除されるレコードに登録されたnameの値") let toBeDeletedRecords = realm.objects(User.self).filter("name = '\(toBeDeletedUserName!)'") try! realm.write { //該当する名前のレコードを全て削除 for element in toBeDeletedRecords{ realm.delete(element) } } |
<h3>RealmSwiftでのUpdate処理</h3>
1 2 3 4 5 6 7 8 9 10 11 |
let realm = try! Realm() let toBeUpdatedUserName = "更新するレコードに登録されたnameの値" print("\(toBeUpdatedUserName!):更新するレコードに登録されたnameの値") let toBeUpdatedRecords = realm.objects(User.self).filter("name = '\(toBeUpdatedUserName!)'") try! realm.write { //該当する名前のレコードを全て更新 for element in toBeUpdatedRecords{ element.name = "更新後のnameの値" element.updated_at = Date() } } |
<h3> RealmSwiftのCRUD </h3>
CRUD確認用アプリを作成。
コード全文は下記の通り
モデルクラス
1 2 3 4 5 6 7 8 9 10 11 12 |
//User.swift import Foundation import RealmSwift class User: Object { @objc dynamic var name:String = "" @objc dynamic var age:Int = 0 @objc dynamic var time:Double = 0.0 @objc dynamic var created_at:Date = Date() @objc dynamic var updated_at:Date = Date() } |
CRUD操作と表示を行うViewController
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 |
// ViewController.swift import UIKit import RealmSwift class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var ageLabel: UILabel! @IBOutlet weak var timeLabel: UILabel! @IBOutlet weak var nameField: UITextField! @IBOutlet weak var ageField: UITextField! @IBOutlet weak var timeField: UITextField! @IBOutlet weak var saveButton: UIButton! @IBOutlet weak var fetchButton: UIButton! @IBOutlet weak var userTableView: UITableView! @IBOutlet weak var preUpdateRecordLabel: UILabel! @IBOutlet weak var postUpdateRecordLabel: UILabel! @IBOutlet weak var preUpdateRecordField: UITextField! @IBOutlet weak var postUpdateRecordField: UITextField! @IBOutlet weak var updateButton: UIButton! @IBOutlet weak var deleteRecordLabel: UILabel! @IBOutlet weak var deleteRecordField: UITextField! @IBOutlet weak var deleteButton: UIButton! var userArray:[User] = [] override func viewDidLoad() { super.viewDidLoad() self.userTableView.delegate = self self.userTableView.dataSource = self } //保存処理 @IBAction func tapSaveButton(_ sender: Any) { let realm = try! Realm() let user = User() user.name = nameField.text ?? "" user.age = Int(ageField.text ?? "0") ?? 0 user.time = Double(timeField.text ?? "0.0") ?? 0.0 user.created_at = Date() try! realm.write { realm.add(user) //データの保存先のパスを取得。Realmブラウザで保存データを確認するときはこのパスを開く。 print(Realm.Configuration.defaultConfiguration.fileURL!) } } //読み込み処理 @IBAction func tapFetchButton(_ sender: Any) { let realm = try! Realm() let allData = realm.objects(User.self) print("\(allData):Realmに保存した全てのUserレコード") self.userArray = [] for element in allData{ self.userArray.append(element) } self.userTableView.reloadData() } //削除処理 @IBAction func tapDeleteButton(_ sender: Any) { let realm = try! Realm() let toBeDeletedUserName = self.deleteRecordField.text print("\(toBeDeletedUserName!):削除されるUserレコードに登録されたnameの値") let toBeDeletedRecords = realm.objects(User.self).filter("name = '\(toBeDeletedUserName!)'") try! realm.write { //該当する名前のレコードを全て削除 for element in toBeDeletedRecords{ realm.delete(element) } } } //更新処理 @IBAction func updateButton(_ sender: Any) { let realm = try! Realm() let toBeUpdatedUserName = self.preUpdateRecordField.text print("\(toBeUpdatedUserName!):更新されるUserレコードに登録されたnameの値") let toBeUpdatedRecords = realm.objects(User.self).filter("name = '\(toBeUpdatedUserName!)'") try! realm.write { //該当する名前のレコードに登録された名前を、更新 for element in toBeUpdatedRecords{ element.name = self.postUpdateRecordField.text ?? "" element.updated_at = Date() } } } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.userArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "userTableViewCell", for: indexPath) cell.textLabel?.text = self.userArray[indexPath.row].name return cell } } |
Realmに格納されたデータを視覚的に分かりやすく確認したいときは、Realm Browserが便利でした。
https://itunes.apple.com/jp/app/realm-browser/id1007457278?mt=12
なお、RealmSwiftには、AutoIncrement機能はないようなので、IDをユニークなものにしようとすると、自前で実装するしかないようです。
それはまた別記事で行おうと思います。
追記)
モデルクラスに下記のように追加することで、新規にレコード追加した際にユニークキーを降ることができるようです。
@objc dynamic var uniqueID:String = NSUUID().uuidString
こちらは下記リンクの記事を参考にさせていただきました。ありがとうございました!
https://qiita.com/kotala_b/items/68b9608df6c8bac80f67
追記
下記のように、今回のケースではモデルクラス内のメンバ変数の値はいずれの書き方でもとってこれる。ただ、別のプロジェクトで使ったところ、element[“メンバ変数の名前”]の形でとってこなければ、保存した値をとってこれず、モデルクラスの初期化の際に入る値(例えば、Double型なら0.0など)が入ってしまうことがあった。
→原因は、モデルクラスのメンバ変数に、dynamicをつけ忘れていたことでした。dynamicをつけていれば、いずれの方法でもきちんと保存したものをとってくることができるようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
//読み込み処理 @IBAction func tapFetchButton(_ sender: Any) { let realm = try! Realm() let allData = realm.objects(User.self) print("\(allData):Realmに保存した全てのUserレコード") // let filterdData = realm.objects(User.self).filter("name = '山田花子'") // print("\(filterdData):nameが山田花子のUserレコード") self.userArray = [] for element in allData{ self.userArray.append(element) //下記のいずれの書き方でも、モデルクラスのメンバ変数の値をとってこれる。 print("\(element.name):element.nameの値、\(String(describing: element["name"]!)):element['name']の値") } self.userTableView.reloadData() } // 相川:element.nameの値、相川:element['name']の値 井上:element.nameの値、井上:element['name']の値 上田:element.nameの値、上田:element['name']の値 |