Hatena::Groupiphone-dev

iOS プログラミングメモ

2014-10-16 (Thu)

iCloud + CoreData の動作でわかんないことがあるんで整理 18:10  iCloud + CoreData の動作でわかんないことがあるんで整理 - iOS プログラミングメモ を含むブックマーク

iCloud + CoreData でデータベーススキーマの更新が思う通りにいかない。そもそも根本的な理解が足りない部分があるのかなあ。まとめるために書きなぐり。

スキーマを更新したい場合はLightweight Migrationだけ対応してるってことで、これはデータモデルの「Add Model Version」をしてModel VersionのCurrentのところを変更するっていう、普通にCoreDataを使っている場合にもやるやり方だと思うんだけど…。

When you use the SQLite store with iCloud, the store supports only lightweight migration.

Page Not Found - Apple Developer

これだけだとデバイス間の同期が期待通りに行なわれない。

具体的には

  1. デバイスAで登録した内容をデータAとする
  2. デバイスBで登録した内容をデータBとする
  3. この段階ではデバイスA・BでそれぞれデータA・Bが両方表示されていて、同期も問題なく超いい感じ
  4. デバイスAで、スキーマを変更したアプリにアップデートすると、データAのみ表示される、データB(他のデバイスで登録した内容)はどっかいって戻ってこない
  5. デバイスBでアプリをアップデートすると、デバイスAにデータBが戻ってくる
  6. 以降はデバイスA・Bで同一の内容が同期される

つまり、片方のデバイスを失くすと、そのデバイスで登録した内容も一緒に失われる状態。悲しい。

iCloud内のデータ(Macだと~/Library/Mobile Documents/)を見たりして、いま理解できているのは

  • iCloud上には、データベースのトランザクションログが記録される
  • ログが格納されるフォルダは、「デバイス固有のUUID(?)/NSPersistentStoreUbiquitousContentNameKeyで指定した名前/データベースモデルのハッシュ」みたいな感じ
  • → ようするに、デバイス毎+データベースのバージョン毎に別々にトランザクションログが記録される
  • iCloud+CoreDataの同期の実装は、他のデバイスのトランザクションログをダウンロードしてきてローカルに適用する形
  • → ただし、適用するのはデータベースモデルのハッシュが同じものに限る
  • モデルの内容を変更したアプリを実行すると、データベースモデルのハッシュが変わり、そのデバイスで使うiCloud上のログ格納ディレクトリも新しく作られる
  • → その実行したデバイスで登録したトランザクションログに限って、この時作られる新しいフォルダにコピーされる
  • 新しいデータモデルに対応したアプリを実行しないと、そっちのデバイスで使っているiCloud上のトランザクションログの格納フォルダは古いまま更新されない
  • → [4]でデータが失われたのも、他のデバイスではモデルのバージョンが古いからくさい。

トランザクションログを一箇所にまとめることはできないのか?または他のデバイスのモデルのバージョンが古くても同期する方法はないのか。ようわからん。

トラックバック - http://iphone-dev.g.hatena.ne.jp/ktakayama/20141016