2015年の夏頃からとあるアプリ開発を、進めていて、Realmを使ってみた際の所感をつらつら書きます。
状況
- 自社アプリ開発
- 期限はだいたい2ヶ月
- 社内でのiOSアプリ開発は初
- 事前にCordovaを使ったハイブリッドアプリをテスト開発してみたが、細かいところに手が届かなかったり、Angularに慣れなかったりと不満が出たので、ネイティブ開発に移行 (今思えばCordovaを追求しても良かったかもしれない....)
チームメンバー
- 意思決定者(社内にいる、コードは書かない)
- 配線からhtmlまでなんでもやる人 ←わたしです
- 担当: バックエンド、クライアントのAPIレイヤー・DB・UI作成など諸々
- Apple好きなiOS開発好きなフロントエンドなデザイナー
- 担当: デザイン全般、UIの細かい修正など
Realmを導入した理由
デザイナーはクライアントでDBをつかったことがなく、Web開発でのバックエンドのことは担当外でしたが、それでもDBとのCRUD処理をバンバン書きながら開発してほしかった。
↓
より直感的に使えそうな気がしたRealmを導入
あとRealmBrowserがあるのも高評価でした
工夫したこと
スケジュール調整と誰でもデータをいじれる環境作り
以下の様な感じで進めていきました。
role | phase1 | phase2 | phase3 |
---|---|---|---|
Developer | スキーマ設計・実装(クライアントとサーバーを並行して) | wrapper?便利メソッドの実装、テストデータの用意 | レビューしながら、メソッドやファイル構成などを修正の繰り返し |
Designer | ワイヤー作成・提案・改善、UI設計 | ViewControllerから実装 | レビューしながら、フォームや一覧を実装 |
Phase1. まず最初にスキーマを組み立てる
データをみんなに簡単に扱ってもらうために、なによりもまずデータ構造をきっちり設計して実装しておきました。出来るまではUI設計を進めてもらって、実装に入るスケジュールを調整しました。
Phase2. これを使って下さいというメソッドを用意
ViewControllerなどModelクラス以外からのRealmへの直接アクセスを禁止することを共有して、使うべきメソッドを予め用意しました。
よくありがちなことですが、viewにsqlを書いちゃう様なケースを避けたかったです。徹底していくうちに少しずつこういったケースは少なくなっていきました。
Hoge.all()
Hoge.filteredById()
Hoge.create()
Hoge.upsert()
Hoge.mine()
Hoge.not_this_day()
Phase3. とにかくコードレビュー
データ周りに関してはとにかくレビューを繰り返しました。私自身もrealmを使ったのは初めてだったので、試行錯誤しながら進めました。みんなが心地よく使える様な環境を作ろうとファイル構成やメソッドをいじり続けました。
そんな感じで今もなお実装をすすめています。今ではデザイナーの方も自分からスキーマを書こうとするまでになりました!
Realmは簡単に使えるので、ゴリゴリのエンジニアでない人にとってとてもいい感じです。
悩んだこと
おもに0.96.0にアップデートしてから直面した問題です。トラブルというか悩んだことです。
DoubleにOptionalを定義するときに一手間いる
class Hoge: Object {
dynamic var double? = nil
dynamic var Bool = false
↑のようにはいかず
class Hoge: Object {
let double = RealmOptional<Double>(1.2)
let bool = RealmOptional<Bool>(false)
}
↑こうする。
ここに書いてありました。が気付かずあれれとなっていました。
tryしてもcatchするときどうしよう...
do {
let realm = try Realm()
realm.write { realm.add(myDog) }
}
catch {
print("Error...")
}
↑の様に書いた際に、catchで何をしようか迷い続けました。場合にもよるでしょうが、try!を使って、エラーが出たらCrashさせておこうと決めました。あとから、Slackで以下のようなコメントを見つけ、安心しました。
Xcode7.1で realm-cocoa 0.96.0 をcarthageで入れようとしてもエラーが吐かれる
importしても↓のようなエラーがでしまいました。
error: module file was created by an older version of the compiler; rebuild 'RealmSwift' and try again
このバージョンはDynamic Frameworkを使ったインストールをして対応しました。
StackOverflowのこの件とだいたい同じ内容だと思われるので、今では問題がなくなっている様ですが、まだ試していません。。。
migrationがちょっとやっかい
モデル追加とかカラム名の変更とかなら簡単にすみますが、モデルの変更など大掛かりなものになるとmigrationファイルも汚れてきたり、処理が煩雑になってきてちょっと一歩踏み出せませんでした。サーバー側をRailsで作っているので、Railsのmigrationとくらべてしまうと物足りない気がしてしまいます。
なので、モデルオブジェクトの定義はカチッとするか、クライアントとサーバーのモデル構造の統一にこだわらない様にするかしています。
基となるDBはサーバー側において、クライアントの方はそのコピーという位置づけに考えたら、精神が安定しました。
まとめ
DBに入門する前のデザイナーの方と、Realmを使ったiOS開発について、感想をつらつらと書きました。おそらくRealmを使ったからスムーズな開発が可能だったと思います。ある程度の下準備やフォローは必要でも、実装に問題なく使えるレベルに上げるまでの期間はかなり短かったです。
他にも、スレッドをまたいだときのことや、Android-iOS-Serverでのスキーマ統一やデータのやりとり、migrationでがんばったことなど、またいつか書きます。