#はじめに
Realmを以下の記事を参考に実装しました。
https://qiita.com/pe-ta/items/616e0dbd364179ca284b
以下のリンクから動き確認できます。
https://twitter.com/vex3ex5frd2xcvg/status/1350637210106699777?s=21
そこから色々調べてみたので、自分なりに理解した事を書いてみようと思います。
実装の手順などは、以下の記事から確認してください。
#実装
###① importする
まずはRealmSwift
をimportします。
RealmSwift
が必要な箇所でそれぞれimportしてみてください。
はじめはエラーになりますので、1度ビルドする事でimport出来ます。
import UIKit
// RealmSwiftをimportするとエラーになるが、ビルドしたら治る
import RealmSwift
###② モデルクラスの作成
ファイルの追加でswiftファイルを作成してください。
このファイルでは、Realmで扱うデータの項目とその型を定義します。
要は、このプロパティに値を保存していくイメージになります。
Realmモデルのプロパティには@objc
とdynamic
をつける必要があります。
import Foundation
import RealmSwift
class TodoModel: Object {
@objc dynamic var koumoku: String? = nil
}
###③ viewControllerに変数を用意
Results
は「オブジェクトから返される Realm の自動更新コンテナ型」だそうです。
この変数にデータを追加していくことになります。
// 作成したTodoModel型の変数を用意。
// Realmから受け取るデータを入れる変数
var itemList: Results<TodoModel>!
###④ viewDidLoadでインスタンス化
今回使用するRealmをインスタンス化して使えるようにします。
次に、object()
を使用します。これは()内に指定したデータを全て取得できるものなので、
取得を行い、取得したデータを③で作成した変数に入れます。
override func viewDidLoad() {
super.viewDidLoad()
// Realmをインスタンス化する
let realm = try! Realm()
// objects()はRealmに保存されている指定されたデータを全て取得する!
// object().filter()でさらにフィルタリングして指定することもできるそうです。
self.itemList = realm.objects(TodoModel.self)
}
###⑤ データを追加して保存していく
今回はbuttonを押したらtextFieldに書いた内容が追加されるようにします。
追加・保存を行いたいAction内で書いてみてください。
1.追加していく場所は、②で作成したモデルクラス内のプロパティになりますので、モデルクラスをインスタンス化していきます。
2.textField.text
を②で作成したkoumoku
プロパティに入れます。
3.buttonAction内でもRealmを使うので、viewDidLoad内で作成したように、Realmをインスタンス化します。
4.realm.write
はRealmインスタンスを最新版に更新し、該当する場合は通知を作成すると公式ドキュメントにありました。
2でデータを更新しているので、realm.write
で最新のものを取得しているわけです。
realm.add()
は管理されていないオブジェクトを()内のRealmに追加します。
つまり、realm.add()
で管理されてない(追加したデータ)をRealmに追加して、
realm.write
でその最新バージョンを取得しているわけです。
@IBAction func addButton(_ sender: Any) {
// 1.モデルクラスをインスタンス化。これでアクセスできるようになる!
let instanceTodoModel: TodoModel = TodoModel()
// 2.textFieldの値をぶち込む
instanceTodoModel.koumoku = self.textField.text
// 3.Realmをインスタンス化してデータベースを取得!viewDidLoadでも行ったやつ
let realm = try! Realm()
// 4.textFieldの値をデータベースに追加する
// write は refresh() が呼び出されたかのように Realm インスタンスを最新の Realm バージョンに更新し、該当する場合は通知を生成します。
try! realm.write {
realm.add(instanceTodoModel)
}
self.tableView.reloadData()
}
###⑥ TableViewの実装
itemList
にRealmから受け取ったデータが入っているので、それを使用してTableViewCellを作成していきます。
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.itemList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell1", for: indexPath)
let item: TodoModel = self.itemList[indexPath.row]
cell.textLabel?.text = item.koumoku
return cell
}
###⑦ 削除機能
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
// この中でもRealmを使えるようにインスタンス化
let realm = try! Realm()
if editingStyle == .delete {
// 削除したいデータを検索する。今回はdeleteしたいcellのindexpath.row番目の項目を削除したいので、それをobjectで指定。
let deleteItem = realm.objects(TodoModel.self)[indexPath.row]
do{
// write は refresh() が呼び出されたかのように Realm インスタンスを最新の Realm バージョンに更新し、該当する場合は通知を生成します。
try realm.write{
// 追加の時のaddの削除版
realm.delete(deleteItem)
}
}catch{
print("Error")
}
}
tableView.reloadData()
}
#実際のコード
import UIKit
// RealmSwiftをimportするとエラーになるが、ビルドしたら治る
import RealmSwift
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var tableView: UITableView!
// 作成したTodoModel型の変数を用意。
// Realmから受け取るデータを入れる変数
var itemList: Results<TodoModel>!
override func viewDidLoad() {
super.viewDidLoad()
// Realmをインスタンス化する
let realm = try! Realm()
// objects()はRealmに保存されている指定されたデータを全て取得する!
self.itemList = realm.objects(TodoModel.self)
}
@IBAction func addButton(_ sender: Any) {
// モデルクラスをインスタンス化。これでアクセスできるようになる!
let instanceTodoModel: TodoModel = TodoModel()
// textFieldの値をぶち込む
instanceTodoModel.koumoku = self.textField.text
// Realmをインスタンス化してデータベースを取得!viewDidLoadでも行ったやつ
let realm = try! Realm()
//Realmインスタンスからaddを叩くと、データベースにレコードが追加される
// textFieldの値をデータベースに追加する
// write は refresh() が呼び出されたかのように Realm インスタンスを最新の Realm バージョンに更新し、該当する場合は通知を生成します。
try! realm.write {
realm.add(instanceTodoModel)
}
self.tableView.reloadData()
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.itemList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell1", for: indexPath)
let item: TodoModel = self.itemList[indexPath.row]
cell.textLabel?.text = item.koumoku
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
let realm = try! Realm()
if editingStyle == .delete {
// 削除したいデータを検索する。今回はdeleteしたいcellのindexpathの項目を削除したいので、それをobjectで指定。
let deleteItem = realm.objects(TodoModel.self)[indexPath.row]
do{
// write は refresh() が呼び出されたかのように Realm インスタンスを最新の Realm バージョンに更新し、該当する場合は通知を生成します。
try realm.write{
realm.delete(deleteItem)
}
}catch{
print("Error")
}
}
tableView.reloadData()
}
}
import Foundation
import RealmSwift
class TodoModel: Object {
@objc dynamic var koumoku: String? = nil
}
#起動してみた
ツイートしてあるので、リンク貼っておきます。
https://twitter.com/vex3ex5frd2xcvg/status/1350637210106699777?s=21
#参考サイト
https://qiita.com/pe-ta/items/616e0dbd364179ca284b
https://naoya-ono.com/swift/realm-update-delete/