Realm × Swift2 でデータを保存してみる


## Realm
ここを見ればだいたい何でもわかります → [Realm Swift](https://realm.io/jp/docs/swift/latest/)

とりあえずマルチプラットフォームで、データを保存できるライブラリです。

コードについても、詳細は、リンク先を参照してください。詳しい使い方も。やっぱり公式が一番です。
この記事では、簡単なサンプルを。
次の記事ではUIImageのシームレスなの保存についてと、autoIncrementなidでの管理について書きました。(画面下部のリンク参照)

## cocoapods
cocoapodsでインストールします。

cocoapodsをインストールしていない場合は、Rubyをインストール＆cocoapodsをインストールしてください。

Macでは標準で入っていますので、以下の2コマンドのみでOKです。

```bash
gem install cocoapods
pod setup
```


## 環境
Mac OSX 10.11.6


## プロジェクトの作成
Xocodeからそのままプロジェクト作成する

ターミナルで、プロジェクトのフォルダまで移動後、

```bash
pod init
```

をすると、自動的にPodfileというファイルが作成されます。cocoapodsでは、このファイルに、必要なライブラリの一覧を追加しますので、これを編集します。

```
vim Podfile
```

iでinsertモードに移行後、

use_frameworks!
の前の#が外れていることを確認します。（ついていれば外す、これはSwiftで使う場合には外します）

その後、

```Podfile
target 'プロジェクト名' do
    pod 'RealmSwift'
end
```

上のように、〜〜Testsとついていない、targetとendの間にを入力してEscでコマンドモードに移行、:wqで保存して終了

以上でPodfileの編集は完了になります。

vimの使い方がわからない場合、テキストエディットなどを使っても問題ありません。

```
pod install
```

でインストールが完了し、

>Updating local specs repositories
Analyzing dependencies
Downloading dependencies
Installing Realm (0.96.2)
Installing RealmSwift (0.96.2)
Generating Pods project
Integrating client project
[!] Please close any current Xcode sessions and use `realmSample.xcworkspace` for this project from now on.
Sending stats
Pod installation complete! There is 1 dependency from the Podfile and 2 total
pods installed.

みたいなのが出てきます。（バージョンは異なります）

とりあえず次回からは`(プロジェクト名).xcodeproj`ではなく、`(プロジェクト名).xcworkspace`のファイルを開くように指示されるので従う。
(xcodeprojを開くとモジュールを読み込めず、コンパイルが通らなくなる)

これで準備は完了。

## 開いてみる
Xcodeを一度閉じて、`(プロジェクト名).xcworkspace`を開いてみる。
一度Runしてみて、今までどおり問題なく動作することを確かめてください
(Realmを一度コンパイルする目的もある、コンパイルするまではモジュールとして読み込めない)

エラーが出る場合、Max OSXやXcodeが最新版でない可能性が高いです。

## とりあえずRealmを使ってみる

Userというクラスを作って、それを保存して読みだす流れを試してみよう。

```swift:User.swift
import RealmSwift

class User: Object {
    dynamic var id = 1
    dynamic var name = ""
}
```

クラスの定義。

以下、このクラスに値をセットして、保存する流れを記述する。

```swift:ViewController.swift
import UIKit
import RealmSwift

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let me = User()
        me.name = "はるふ"
        
        let realm = try! Realm()
        try! realm.write {
            realm.add(me)
        }
        
        print(realm.objects(User))
    }
}

```

以上で動く。

`realm.objects(User)`で読みだして、それを直接printしているので、コンソールを見れば、現在のrealmの様子を確認できる。

Runさせるたびに、1つづつ追加されていくので、10回ぐらいすれば、print時に10個のUserオブジェクトが表示されるはずである(内容は同じ)

## コードの説明

```swift
class User: Object {
```

保存可能なクラスは、Object(Realmで定義されたクラス)を継承する必要がある。

また、保存可能なプロパティの型は、

Supported property types
>String, NSString
Int
Float
Double
Bool
NSDate
NSData
RealmOptional<T> for optional numeric properties
Object subclasses for to-one relationships
List<T: Object> for to-many relationships

のみである。(Option+クリックで閲覧可能な、Objectクラスのマニュアルに書いてある)

```swift
dynamic var hogehoge
```

Realmで保存する型は、dynamic属性でなければなりません([Realm Swift 0.96.0](https://realm.io/jp/docs/swift/latest/))


```swift
let realm = try! Realm()
```

swift2からは、エラーを投げる可能性のあるものはtryで囲う必要がある。Realm()の場合、権利問題などで、エラーを投げる可能性がある。
ここでは簡単のため、エラーを無視するコードにしたが、よくはない。下のwrite命令も同様。

```swift
try! realm.write {
	realm.add(instance)
}
```

追加で書き込みを行う。
これは、引数としてクロージャを渡す構文 → [Swift のクロージャについてのメモ](http://qiita.com/taketin/items/03eed7694ee4d39e211d)
トランザクションの開始＆終了を自動的に行ってくれます。

```swift
realm.objects(T)
```

クラスTで定義されたデータのみ、すべて取得する。ここから一部抽出したりする。
Tはタイプを指定する。うえでは、Userを指定しているので、Userで定義されたデータをすべて取得している

```swift
for user in realm.objects(User) {
}
```

とすれば一つ一つ読みだすことも可能です。

## 続き
1つめの記事 → [Realm × Swift2 でデータを保存してみる](http://qiita.com/_ha1f/items/08bbed8b3dc6f9f6cadd)(この記事)
2つめの記事 → [Realm × Swift2 でidでデータを管理する](http://qiita.com/_ha1f/items/f6318e326434dbf83037)
3つめの記事 → [Realm × Swift2 でシームレスに画像を保存する](http://qiita.com/_ha1f/items/593ca4f9c97ae697fc75)