[Realm][Swift4対応 完全保存版] 3.モデルオブジェクトの作成と書き込み

はじめに

前回はRealmにおけるモデルの定義について説明しました。

第3回目となる今回は、モデルからインスタンスを生成してデータを設定し、データベースに書き込むまでを説明します。

過去記事は以下を参照ください。

環境

Xcode:9.4.1
Swift:4.1.2
Realm:3.7.4

目次

モデルオブジェクトを作成する

前回定義した選手モデルから、インスタンスを生成してみましょう。

選手モデルは以下を使用します。

/// 選手モデル
class Player: Object {
    // 選手名
    @objc dynamic var name : String = ""
    // 身長(単位:m)
    @objc dynamic var height : Double = 0.0
    // 体重(単位:kg)
    @objc dynamic var weight : Double = 0.0
    // メモ
    @objc dynamic var memo : String = ""
}

上記モデルからインスタンスを生成してデータを設定するには以下の3種類の方法があります。

  1. 初期化子を指定してオブジェクトを作成
  2. キーと値を指定した辞書からオブジェクトを作成
  3. 配列を使用してオブジェクトを作成

以下に選手モデルを作成する方法を示します。

// (1)初期化子を指定してオブジェクトを作成
let player1 = Player()
player1.name = "Bill"
player1.height = 180.3
player1.weight = 54.5
player1.memo = "genius"

// (2)キーと値を指定した辞書からオブジェクトを作成
let player2 = Player(value: ["name" : "Steve", "height" : 175.2, "weight" : 65.3, "memo" : "creator" ])

// (3)配列を使用してオブジェクトを作成
let player3 = Player(value: ["Tim", 178.0, 62.3, "CEO"])

// 作成したオブジェクトの確認
print(player1)
print(player2)
print(player3)

1〜3のどの方法で作成しても構いませんが、オススメは1 or 3です。ただし、3の配列については、全てのプロパティの値をモデルに定義した順番通り記載する必要があるので、注意が必要です。

2はキーを文字列で指定する必要があり、タイプミスのおそれがあるので個人的には使用していません。

データベースへの書き込みの基本

データを設定しただけでは、データベースに書き込まれることはありません。

データベースに書き込むには、以下の手順で行います。

  1. Realmのインスタンスを生成する
  2. 1で作成したインスタンスの書き込みトランザクション内でデータを追加する

先ほど作成した、選手データをデータベースに書き込む例を以下に示します。

// 初期化子を指定してオブジェクトを作成
let player1 = Player()
player1.name = "Bill"
player1.height = 180.3
player1.weight = 54.5
player1.memo = "genius"

// (1)Realmのインスタンスを生成する
let realm = try! Realm()

// (2)書き込みトランザクション内でデータを追加する
try! realm.write {
    realm.add(player1)
}

上記を実行すると、データベースにデータが書き込まれます。

以下は、書き込まれたデータをRealm Studioというツールで確認した例です。

ちなみに、データベースファイルの保存先は、以下のコードを実行することで確認できます。

// 保存先の表示
print(Realm.Configuration.defaultConfiguration.fileURL!)

1対1のデータを書き込む方法

次に1対1のリレーション関係のあるデータの書き込みについて説明します。

使用するモデルは、TeamとCoachの2つです。「1つのチームに対して1人のコーチがいる」ことを表せるモデルです。

/// チームモデル
class Team: Object {
    // id
    @objc dynamic var id : Int = 0
    // チーム名
    @objc dynamic var name : String = ""
    // コーチ
    @objc dynamic var coach: Coach? //1対1の関係

    // 主キーの作成
    override static func primaryKey() -> String? {
        return "id"
    }
    
    // インデックスの作成
    override static func indexedProperties() -> [String] {
        return ["name"]
    }
}

/// コーチモデル
class Coach: Object {
    // コーチ名
    @objc dynamic var name : String = ""
    // コーチ歴(単位:年)
    @objc dynamic var year : Int = 1
}

上記のモデルからオブジェクトを作成してデータベースへ書き込むまでのコードを以下に示します。

初期化子を指定した方法による1:1のデータ書き込み例
// 「コーチ」オブジェクトの作成
let coach = Coach()
coach.name = "Jhon"
coach.year = 3

// 「チーム」オブジェクトの作成
let team = Team()
team.id = 1
team.name = "Bulls"
team.coach = coach  // 「コーチ」オブジェクトを設定

let realm = try! Realm()

try! realm.write {
    realm.add(team)
}
辞書による1:1のデータ書き込み例
let team = Team(value: ["id" : 1, "name" : "Bulls",
                        "Coach" : ["name" : "Jhon", "year" : 3]
    ])       

let realm = try! Realm()

try! realm.write {
    realm.add(team)
}
配列による1:1のデータ書き込み例
let team = Team(value: [1, "Bulls",
                        ["Jhon", 3]
    ])

let realm = try! Realm()

try! realm.write {
    realm.add(team)
}

上記をRealmStudioで確認した結果を以下に示します。親のteamに対して子のcoachも正しく登録されていることがわかります。

1対Nのデータを書き込む方法

最後に1対Nのリレーション関係のあるデータの書き込みについて説明します。

使用するモデルは、TeamとPlayerの2つです。「1つのチームに対して複数の選手がいる」ことを表せるモデルです。

/// チームモデル
class Team: Object {
    // id
    @objc dynamic var id : Int = 0
    // チーム名
    @objc dynamic var name : String = ""
    // 選手
    let players = List<Player>()    // 1対Nの関係

    // 主キーの作成
    override static func primaryKey() -> String? {
        return "id"
    }
    
    // インデックスの作成
    override static func indexedProperties() -> [String] {
        return ["name"]
    }
}

/// 選手モデル
class Player: Object {
    // 選手名
    @objc dynamic var name : String = ""
    // 身長(単位:m)
    @objc dynamic var height : Double = 0.0
    // 体重(単位:kg)
    @objc dynamic var weight : Double = 0.0
}

上記のモデルからオブジェクトを作成してデータベースへ書き込むまでのコードを以下に示します。

初期化子を指定した方法では、はじめに3人の選手データ(player1〜player3)を作成します。次に選手用のリスト(players)に3人のデータを追加(appendメソッドを使用)します。チームのデータ作成時は、選手の追加メソッド(players.appendメソッド)を使用して、作成したリストを設定しています。

初期化子を指定した方法による1:Nのデータ書き込み例
// 1人目の選手
let player1 = Player()
player1.name = "HIRO"
player1.height = 163.0
player1.weight = 60.5

// 2人目の選手
let player2 = Player()
player2.name = "CHIHIRO"
player2.height = 175.0
player2.weight = 58.0

// 3人目の選手
let player3 = Player()
player3.name = "SHURI"
player3.height = 170.0
player3.weight = 61.2

// 上記で作成した3人の選手を格納するリストの作成
let players = List<Player>()
players.append(player1)
players.append(player2)
players.append(player3)

// チームの作成
let team = Team()
team.id = 1
team.name = "Bulls"
team.players.append(objectsIn: players)


let realm = try! Realm()

try! realm.write {
    realm.add(team)
}

次に辞書を使用した1:Nの書き込み例を指定します。teamのキー”players”は、[]を使用して入れ子にし、3人分のデータを設定しています。

辞書による1:Nのデータ書き込み例
let team = Team(value: [
    "id" : 1,
    "name" : "Bulls",
    "players" : [
        ["name" : "HIRO", "height" :  163.0, "weight" : 60.5],
        ["name" : "CHIHIRO", "height" :  175.0, "weight" : 58.0],
        ["name" : "SHURI", "height" :  170.0, "weight" : 61.2]
    ]
])

let realm = try! Realm()

try! realm.write {
    realm.add(team)
}

最後に配列を使用した1:Nの書き込み例を指定します。teamのキー”players”は、[]を使用して入れ子にし、3人分のデータを設定しています。

配列による1:Nのデータ書き込み例
let team = Team(value: [
    1, "Bulls",
    [
        ["HIRO", 163.0, 60.5],
        ["CHIHIRO", 175.0, 58.0],
        ["SHURI", 170.0, 61.2]
    ]
])

let realm = try! Realm()

try! realm.write {
    realm.add(team)
}

上記をRealmStudioで確認した結果を以下に示します。親のteamに対して子のplayersが正しく登録されていることがわかります。

次回

今回は、データの書き込み方法について説明しましたので、次回はデータの読み取り方法について説明します。

2 Replies to “[Realm][Swift4対応 完全保存版] 3.モデルオブジェクトの作成と書き込み”

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください