#はじめに
watchOSとiOSとの間でRealmのデータをやりとりする実装方法について述べます。
watchOS2+、iOS9+、Swift 3を前提に話を進めます。
動作するコードをサンプルプロジェクトとしてGitHubに公開しました。実機でランすれば、速度感を体験できます。
#基本的な考え方
iOS-watchOS間でRealmファイルを共有したい場合、かつてwatchOS 1の時代では、iOS側が親、watchOS側が子となり、子は親のRealmファイルそれ自体を参照するという考え方をとっていました。(watchOS 1については、こちらの資料をご覧ください。RealmとApp Extensionのガイダンス/Realm meetup vol.6)
これに対して、watchOS 2以降では、iOS側とwatchOS側のRealmファイルはそれぞれ別個の実体となります。このため、何らかの方法でファイルを同期する必要が生じます。
今回は、iOS側のRealmファイルをfileTransfer()でwatchOS側にファイル転送する、という考え方をとります。実装をシンプルに済ませることができるからです。
同期の方法としては、差分をupdateApplicationContext()で送り、内容的一致をとる方法もありえます。確かに、転送データに無駄がないので、ファイルが大きい場合は転送スピードや省エネの面で有利になる可能性があります。しかし、ファイルサイズが極端に大きくない場合、実装しやすさの価値のほうが大きいと判断し、今回はfileTransfer()の方法を採用しました。
サンプルプロジェクトを通じて実装の勘所をメモしていきたいと思います。
#サンプルのゴール
サンプルとしてどんなものかを作るか。
iOS側でtextFieldを入力すると、Realmに保存され、その内容が逐次、watchOS側のLabelに反映されるものを作ることにします。
実装の方針
- iOS側のtextFieldの変更毎にRealmにテキストを保存する。
- 変更時に、iOS側のRealmファイルをWCSessionのfileTransfer()でwatchOS側にファイル転送する。
- 届いたら、watchOS側のRealmファイルを刷新し、内容を取り出してwatchOS側のLabelに表示する。
#サンプルコードの実行
SampleRealmOnWatchOS3
https://github.com/hsylife/SampleRealmOnWatchOS3
このサンプルでは、転送速度の比較のために、sendMessageによって直接データを送信する方法も実装しています。
- GitHub上のリポジトリをクローンします。
- RealmSwiftをImportするために、ターミナルを起動し、CocoaPodsの
pod install
を実行します。 - シミュレータで動作確認したい場合、スキームをwatchOSにしたまま、Runします。watchOSアプリを起動します。
- iOSアプリを起動します。
- アプリで表示されているステップの通りに、iOSアプリ側のtextFieldにテキストを入力すると、watchOS側に反映されます。