Takahiro Octopress Blog

-1から始める情弱プログラミング

Swift3でRealmSwiftを使ってみよう!

はじめに

約2年前に画期的なモバイルデータベースとしてRealmについて紹介させて頂きました。
当時はSwift専用のものがなかったため、Objective-C用のものをブリッジヘッダーファイルを作成することで利用していました。
現在はかなり多くのアプリでも利用され、広く浸透していると共に、SwiftRealmが作られ、Swift専用化しています。

今回は、以前、筆者が書いたSwiftでRealmを使ってみよう!SwiftRealmで書き直す形でSwift3でのRealmの使い方を見ていきたいと思います。

RealmSwiftの導入方法

CocoaPodsを利用して導入してみます。
(Carthageでの利用方法も公式サイトにて紹介されています。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Podfile
use_frameworks!

target "RealmSwiftSample" do
  # Normal libraries
  pod 'RealmSwift'

  abstract_target 'Tests' do
    inherit! :search_paths
    target "RealmSwiftSampleTests"
    target "RealmSwiftSampleUITests"
  end
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '3.0'
    end
  end
end

因みに、abstract_targetは複数targetにまたがって利用したいライブラリがある場合に利用します。
(上記の例はテストでのみ利用するライブラリがある場合に利用する書式です。)
また、post_install do |installer|endまでの書式はSwiftのバージョンを指定するために追加します。

Podfileができたらpod installを実行してxcworkspaceファイルを開きましょう。

保存オブジェクトの生成

Objective-C用のときはRLMObject型のクラスを作成していましたが、RealmSwiftでは単にObject型のクラスを作成します。

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
// Engineer.swift

import Foundation
import RealmSwift

// Skillクラス
class Skill: Object {
    dynamic var name: String = ""
}

// Engineerクラス
class Engineer: Object {
    dynamic var id: Int = 0
    dynamic var name: String = ""
    dynamic var level: Int = 0
    let skills = List<Skill>()
    dynamic var created: Double = Date().timeIntervalSince1970
    dynamic var updated: Double = Date().timeIntervalSince1970

    // プライマリーキーの設定
    override static func primaryKey() -> String? {
        return "id"
    }

    // インデックスの設定
    override static func indexedProperties() -> [String] {
        return ["level"]
    }
}

Objective-C用のRealmではRLMArray型としてskillsを作成していましたが、RealmSwiftではList<Skill>型として作成できます。
こちらの方が直感的でわかりやすいですね。
因みに、dynamic var skills = List<Skill>()と書くとエラーが発生するのでListを利用する場合はletにしましょう。

オブジェクトのインサート/アップデート

先程作成したオブジェクトを保存する方法について紹介しましょう。

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
// ViewController.swift
import UIKit
import RealmSwift

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // 新規オブジェクトをインサート
        createEngineer(name: "test1", level: 1, skills: ["swift", "objective-c"])
    }

    <省略>

    func createEngineer(name: String, level: Int, skills: [String]) {
        // Skill型オブジェクトに変換してList<Skill>に格納
        let skillList = List<Skill>()
        for skill in skills {
            let newSkill = Skill()
            newSkill.name = skill
            skillList.append(newSkill)
        }

        let realm = try! Realm()

        // Engineer型オブジェクトの作成
        let engineer = Engineer()
        engineer.id = realm.objects(Engineer.self).count
        engineer.name = name
        engineer.level = level
        engineer.skills.append(objectsIn: skillList)

        // Realmへのオブジェクトの書き込み
        try! realm.write {
            realm.add(engineer)
        }
    }
}

Objective-Cの際はrealm.beginWriteTransaction()realm.commitWriteTransaction()などわざわざ書いていたものの、RealmSwiftでは非常にコンパクトに書けますね。
因みに、アップデートであれば、

1
2
3
try! realm write {
  engineer.name = "takahiro"
}

のようにすれば良さそうです。

データの確認

今は、Mac App StoreからRealm Browserアプリをインストールすることで簡単にデータ確認が可能になっています。

手順は以下の通りです。
1.Realm Browserを起動する
2.Realmファイルを選択して開く

そうすることで、下記のようにデータを確認することができます。

Realm BrowserでEngineerオブジェクトを確認
Realm BrowserでSkillオブジェクトを確認

注意すべきこととしては、シミュレータだとrealmファイルを探すのに骨が折れるかもくらいでしょうか…
/Users/<username>/Library/Developer/CoreSimulator/Devices/<simulator-uuid>/data/Containers/Data/Application/<application-uuid>/Documents/default.realmにありますので該当するファイルを検索するなどして探しましょう。

まとめ

さて、如何でしたでしょうか。
筆者は久しぶりにRealmを触ったため、以前利用していたときよりも『だいぶ変わったな』と正直思いました。
ですが、RealmSwiftになったことで、よりSwiftらしい書き方ができると思いますし、単純に記述量も少なく書けるような気がしています。
今後も多くのアプリで利用されることでしょうし、知っておいて損は絶対になさそうですね。
ということで本日はここまで。

参考:

Comments