Realmで日記アプリを作った時の備忘録 (Swift)


はじめに

Realm×FSCalendarで日記アプリを作ってみたのでその時の備忘録を残そうかと.

プロジェクト

Realm×FSCalendarで日記アプリを作ってみた

環境

  • Realm 3.11.1
  • Swift 4.2
  • Xcode 10.1

Realmとは?

モバイル向けNoSQLデータベースです.
NoSQLとは言葉の通りSQLではないデータベースのこと(Not Only SQL)です.
SQLといえばテーブルを作ってカラムを宣言してダミーのデータをあらかじめ用意しておいて...と複雑な手順が必要ですよね (SQLロクに触ったことないので詳しくはわかりませんが...)
SQLの問題点を解決したのがNoSQLだそうです.
ちなみに名前のとうりNoSQLの定義は大雑把でそのためNoSQLにもいくつか種類があるのですが,

この図で言うとカラム指向型にRealmは当たると考えています.間違いがあればご指摘願います.

カラム指向型とは

  • カラム指向型
    • 一般の行指向型DBと同様に表の構造を持ちつつ、カラム単位でデータを保持する。
    • 行指向では苦手な列単位の大量集計、大量更新が得意。

引用: NoSQLについて勉強する。

とのことです.

SwiftでのRealmの3つのルール基礎編

1. Realmのインスタンス生成時にキャッシュが参照される

let realm = Realm()

Realmのデータベースはこのように作成しますよね
Realmはこの時点でキャッシュが作成されるのでもう一度新たにインスタンスを作成した時に同じインスタンスを参照します.

let realm = try! Realm() //Realmのデータベースを作成

let realm2 = try! Realm() //Realmのデータベースを作成. ここのrealm2はrealmと同等のrealm

2. データの変更はrealm.writeメソッドの中で書かないといけない

Realm×FSCalendarで日記アプリを作ってみたのコードを参考にすると

let diary = Diary()
diary.title = "Hello World!"
try! realm.write {
    realm.add(diary)
}

このようにトランザクション内でデータベースへの更新処理を書かないといけないといけないようです.

そんなに気にしなくて大丈夫で一旦こういうものだと言う認識でいいと思います.

また、Realmのデータ更新はディスクの領域が足りなくなった時などにエラーから回復することを想定しtryで書いているようです.

3. RealmのObjectクラスのプロパティには@objc dynamicを先頭につける

これもルールなんだと言う認識でいいと思います.
以下のように書きます.

class Diary: Object {

    @objc dynamic var title: String = ""
    @objc dynamic var content: String = ""
    @objc dynamic var date: Date!
}

SwiftでのRealmの2つのルール応用編

1. StandAloneなオブジェクトはrealmの更新をrealm.writeのなかで書かなくてOK

  • StandAloneなオブジェクトの例
let diary = Diary()
// データの更新
diary.title = "new title" // 落ちない
  • StandAloneではないオブジェクトの例
let diary = realm.objects(Diary.self).first!
// データの更新
diary.title = "new title" // 落ちる

このようにRealmデータベースに紐づいていないオブジェクトをStandAloneといいます.

2. カラムの変更をしたらマイグレーションをしないといけない

書き方があるのでそれを紹介します.

let config = Realm.Configuration(schemaVersion: 0, migrationBlock: { (migration, version) in
    if version < 0 {
    }
})

Realm.Configuration.defaultConfiguration = config

これをAppDelegatedidFinishLaunchingWithOptionsを引数としているメソッドに書いてあげてください.

カラムを更新したらschemaVersionの数を今の数字より大きくしてあげてください.

こんな感じになります.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    //MARK: - migrationのコード
    let config = Realm.Configuration(schemaVersion: 0, migrationBlock: { (migration, version) in
        if version < 0 {
        }
    })

    Realm.Configuration.defaultConfiguration = config
    //MARK:-

    return true
}

最後に

以上でまとめを終わります.

最後まで読んでいただきありがとうございました〜

参考記事