【Realm】

データを登録・更新(Insert・Update)する方法

addメソッドの使い方と.modified

投稿日 2021/04/18 更新日 2021/09/26


こんにちは。当サイトの管理者「元木皇天」です。

今回は、Realmを使用してデータを登録・更新する方法について解説いたします。

環境
OS:MacOS Big Sur
Xcode:バージョン12.3
Swift:バージョン5.3
Realm:バージョン10.5.1

やりたいこと

①モデルオブジェクトにデータを登録する。

②モデルオブジェクトのデータを更新する。

事前準備

まずは事前準備として、Realmに登録するモデルオブジェクト(一般的DBのテーブル)を作成します。

作成の仕方は過去の記事で紹介しているのでそちらを参考にしてください。

【Realm】SwiftUIにRealmを導入する方法

【Realm】Realmでテーブル(モデル)を作成する方法

【Realm】Primary Key(プライマリーキー)を設定する方法

過去の記事同様に、今回はUserTableというモデルにデータを登録・更新を行っていきます。

UserTableモデルは以下のような構造になっています。IDとユーザ名を持つモデルです。

import Foundation
import RealmSwift

class UserTable: Object{
    //ユーザID
    @objc  dynamic var ID: Int = 0
    //ユーザ名
    @objc  dynamic var userName: String = ""
}

データの登録(PKなし)

Realmでは、PKを持つか持たないかで、データを登録するさいのメソッドの引数に違いがでます。

まずはわかりやすいように、PKを持たない場合のInsert処理を行いたいと思います。

なお、今回はボタンを押したら登録する、など余計なコードはみやすさの都合上省略し、init()のなかで全て処理を行いますのであらかじめご了承ください。

データの登録処理は、必ず書き込みトランザクションのなかで行います。

書き込みトランザクションは以下のように記述します。

//デフォルトRealmの取得
let realm = try! Realm()

//書き込みトランザクション開始
try! realm.write{
    //書き込み処理を記載する
}

そして、このトランザクション処理の中に、どのデータをどのモデルに登録するか、という処理を記載します。

データを登録するときはadd()メソッドを使用します。

では実際にデータを登録して、画面に表示してみましょう。

コードは以下の通りです。

import SwiftUI
import RealmSwift

struct ContentView: View {
    var allUser:Results<UserTable>?

    init(){
        //デフォルトRealmの取得
        let realm = try! Realm()
        //追加するデータの生成
        let user:UserTable = UserTable(value: ["ID" : 1 ,
                                               "userName" : "user1"])
        try! realm.write{
            //データの追加
            realm.add(user)
        }

        //データの取得
        allUser = realm.objects(UserTable.self)
    }

    var body: some View {
        VStack(){
            Text("登録されたユーザ")
            Text(allUser![0].userName)
        }
    }
} 
登録したデータの表示

init()のなかで登録したデータが画面上に表示されていることが確認できました。

登録するデータは、登録するモデルのカラム名とそこに登録したいデータをセットで記載して作成します。

そしてそのデータを書き込みトランザクション内で呼び出したadd()メソッドの引数に渡すことで、登録が完了します。

そこまで難しくないことがわかりますね。

次はPKを持つモデルへのデータの登録方法について解説いたします。

データの登録・更新(PKあり)

PKありのInsert処理はほんの少しだけ先ほどとは異なります。

まずは、先程のUserTableモデルは破棄して新たに以下のUserTable2モデルを作成してください。

import Foundation
import RealmSwift

class UserTable2: Object{
    //ユーザID
    @objc  dynamic var ID: Int = 0
    //ユーザ名
    @objc  dynamic var userName: String = ""

    //Primary Keyの設定
    override static func primaryKey() -> String? {
        return "ID"
    }
}

IDカラムをPKに設定しました。

では早速データを追加する処理を記載していきましょう。

import SwiftUI
import RealmSwift

struct ContentView: View {
    var allUser:Results<UserTable>?

    init(){
        //デフォルトRealmの取得
        let realm = try! Realm()
        //追加するデータの生成
        let user:UserTable2 = UserTable2(value: ["ID" : 1 ,
                                                "userName" : "user1"])
        try! realm.write{
            //データの追加
            realm.add(user, update: .modified)
        }

        //データの取得
        allUser = realm.objects(UserTable2.self)
    }

    var body: some View {
        VStack(){
            Text("登録されたユーザ")
            Text(allUser![0].userName)
        }
    }
}

赤線で引いたように、先ほどと違いadd()メソッドの第二引数に値を渡しています。

この第二引数は、PKが被ったデータがInsertされる場合どうするかを設定する値です。

今回設定した.modifiedは、登録するデータのPKが被った場合Update(更新)するという処理になります。

PKが被っていなかった場合は、新規でデータが登録されます。

では、先ほど実行したコードのデータを一部変更して更新処理を行なってみましょう。

コードは以下になります。

import SwiftUI
import RealmSwift

struct ContentView: View {
    var allUser:Results<UserTable>?

    init(){
        //デフォルトRealmの取得
        let realm = try! Realm()
        //追加するデータの生成
        let user:UserTable2 = UserTable2(value: ["ID" : 1 ,
                                                "userName" : "user1111"])
        try! realm.write{
            //データの追加
            realm.add(user, update: .modified)
        }

        //データの取得
        allUser = realm.objects(UserTable2.self)
    }

    var body: some View {
        VStack(){
            Text("登録されたユーザ")
            Text(allUser![0].userName)
        }
    }
}

実行すると、画面に表示されるユーザ名が更新されて表示されていることがわかります。

更新したデータの表示

まとめ

Realmを使用してデータを登録(Insert)する場合はadd(Object)を使用する。

PKがあるデータの場合はadd(Object, update: XXX)のように第二引数を指定して実行する。

※今回使用したコードの全体をいかに載せておきますので何かの参考にしていただけたら嬉しいです。

Realmでデータを更新するコードの全体像

参考文献・おすすめ文献

関連記事

元木皇天

化学系大学出身
現在は3年目SEとして
日々がんばっています

Twitter