Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

SansanのEightアプリでRealmを導入した件

1,601 views

Published on

Realm meetup #3で話したスライドです

Published in: Technology
  • Be the first to comment

SansanのEightアプリでRealmを導入した件

  1. 1. Sansanの Eightアプリ でRealmを導入した件 Realm meetup #3 @yimajo(今城 善矩) 2015.5.21
  2. 2. 自己紹介 • 株式会社キュリオシティソフトウェア • Sansan社のEight事業部で非常駐的に開発業務 を委託されている • Realm対応などを担当した • 木曜日午後に打ち合わせに来てる
  3. 3. Realm導入について実践的な 話をしようと思いますが Eight iOSアプリの背景を 話しつつ進めていきます https://8card.net/
  4. 4. 目次 • はじめに Realm導入の背景…5分 • Realmをどの機能で使ったか…5分 • なぜRealmを選んだか…5分 • Realmを導入してみての知見…10分
  5. 5. はじめに
  6. 6. Eight iOSアプリとは
  7. 7. • Eight事業部は岸川さんや堤さん(@shu223)と いうiOS開発者とも契約している • 2人とも非常駐的に仕事をしている • 2人はたまにSansan社に来ることがある!
  8. 8. 先月4月はこんな感じ 岸川さんと堤さんが週替りで打ち合わせに来る!!!!
  9. 9. どうやってる?
  10. 10. masterブランチ developブランチ BLE対応ブランチ Realm対応ブランチ 細かなトピックブランチ ブランチ利用のイメージ
  11. 11. 岸川さんの役割的な場面
  12. 12. Realmをどの機能で 使ったか
  13. 13. • Eight iOSのお知らせ一覧 • ユーザに色々な内容を運営か らお知らせするWeb APIがあ りそれをキャッシュする • この機能は比較的重要ではな い • 元々はplist形式で保存されて いた ※写真のデータはダミーです
  14. 14. なぜRealmを使う?
  15. 15. Eight(iOS)の永続的な データ保存について(before) • SQLite • 検索、並び替え、更新があ るデータに利用 • plist • キャッシュ的な利用 • その他 • 撮影画像を直接特定のディ レクトリ下に連番で置く等 その他 4% plist 11% SQLite 85%
  16. 16. PhoneGapで HTML5時代 (マルチプラットフォーム!!) ネイティブ化し 外注で開発時代 引き継いだコードで 内製化 歴史
  17. 17. なぜRealmを使う? • 古い実装では、データがViewControllerでNSDictionary を扱うようなコードになってしまっている • これ以上オレオレO/Rマッパーを挟むのも技術的負債を 増やしかねない • しっかりとしたO/Rマッパーが用意されてあれば使いた い • Android版Eight もありそちらで使いたいという声も大 きかった
  18. 18. まず 影響度の少ない既存の機能の保存 部分からRealmに置き換え 調査を兼ねた方法を とることになった
  19. 19. Realm導入に対する知見 Realm(cocoa) v0.90.6
  20. 20. 打順 守備 選手名 1 遊 サンプルコードが実践的なガイドになってるので読もう 2 二 RLMObjectサブクラスのプロパティ定義がカラムを示す 3 中 NSNull/nilで保存できない 4 一 NSStringはnilを保存するように見えて空文字を保存する 5 右 NSDate使いづらいのでNSStringで保存した 6 三 Realm+JSONが自動でISO8601形式の文字列をNSDateに してしまう 7 左 JSONExportのコードはnilを考慮していない 8 捕 RLMObjectのプロパティ属性は書かないほうが良い 9 投 NSIntegerじゃなくint64_tを使うべき時もある 開発時の最新であったRealm(cocoa) v0.90.6を使用。バージョンアップにより仕様も変わるため内容は鵜呑みにしないでください
  21. 21. 一部を抜粋して 説明します
  22. 22. サンプルコードが実践的で重要
  23. 23. • リファレンス読んだら次は公式サンプルコードを 絶対読もう • EightのアプリではTable Viewのサンプルを参考 にした。最初これを読まずに嵌ったので読もう • 非同期でのデータ書き込み、書き込み完了通知、 表示についてよく分かる • https://github.com/realm/realm-cocoa/ tree/master/examples/ios/objc/TableView
  24. 24. JSONExportのコードはnullを 意識していないので カスタマイズして使う
  25. 25. JSONExportとは • JSONExportはJSONのファイルからクラスを定 義してくれるツール • マッピング用のメソッドのコードも生成して出 力してくれる https://github.com/Ahmed-Ali/JSONExport
  26. 26. JSONExportとは https://github.com/Ahmed-Ali/JSONExport
  27. 27. 例 - (instancetype)initWithDictionary:(NSDictionary *)dictionary { if(dictionary == nil || [dictionary isKindOfClass:[NSNull class]]){ return nil; } self = [super init]; if(![dictionary[@"id"] isKindOfClass:[NSNull class]]){ self.identifier = [dictionary[@"id"] integerValue]; } if(![dictionary[@"name"] isKindOfClass:[NSNull class]]){ self.name = dictionary[@"name"]; } return self; } ただdictionary[@ id ]がnilなら_identifierもnilになり例外が 起きるので、この条件自体もカスタマイズは必要になる
  28. 28. Eightでは JSON+Exportで自動生成される コードを元に カスタマイズしていきました
  29. 29. NSDateが使いづらいので NSStringで保存した
  30. 30. EightはWebAPIでJSONを取 得し保存したい { "messages":[{ "message":{ "id":1, "status":0, "kind":201, "link":1, "announced_datetime":"2014-08-19T22:54:02+09:00", "datetime_from":"2014-08-19T22:54:02+09:00", datetime_to":null   } }] } JSONで日時のデータがnullだったりする
  31. 31. Realmでnil/NSNull保存 できない • 日付がないってどうやって表す? 下記が検討内容 1. 型はNSDateで、ダミー用の特定の日時が保存されてい たら日付なしと扱う 2. 型をdoubleにしてUNIX時間(since1970)もしくはApple 時間(sinceReferenceDate)を基準にし、0なら日付なし 3. 日付の項目がnullだというフラグの項目を別に持たせる 4. 型はNSStringで保存する
  32. 32. NSDateで特定の値をnull相 当として入れる案 • その特定の値がnull相当だと決めるのが実装になってし まい非常にあと引く設計でダメだ • ドキュメントにその特定の値がnull相当だと書けばいい とかいうのも良くない • (そもそも外部取得してる値なんだから何がくるか分か らないと思ったほうがいい) • 今回はこの方法はパス
  33. 33. 型をdoubleにして基準値を決 め差分を保存 • UNIX時間(since1970)もしくはApple時間 (sinceReferenceDate)の基準を使う • 保存されている値に対して基準が何かは誰が知っている? • コードに書いてある or ドキュメントに書く • あんまりイケてないのでは… • 今回はこの方法はパス
  34. 34. 日付を保存する項目がnilであ るという項目を別に作る • しかたないがアリな方法 • ただしnil/NSNullが保存できるようになった場合 にその方法が残ると直したくなるしあまりイケ てないのでは… • 当然その方法で実装したくなる場面というのは あるが今回はパス
  35. 35. NSStringで保存 • JSONから取得する日時は"2014-08- 19T22:54:02+09:00"のようにISO8601形式になって いる • これはそのまま文字列として保存し利用する際にNSDate にする • NSStringは空文字@ という概念があるので日時がない ものは空文字として保存すれば利用時に判別できる • まあまあこれは良さそうなのでこれを選んだ
  36. 36. まとめ
  37. 37. • 既存のアプリでRealm対応する場合は • 比較的軽い機能から対応すると気軽 • JSONExportなどのツールを使うと便利
  38. 38. 以上です

×