はじめに

この記事は、SwiftでiOSアプリを開発していて「iCloudのKey-Value Storeを使えばデバイス間でデータが同期されるはず…なのに反映されない!」と頭を抱えている開発者向けです。

Appleのドキュメントには「NSUbiquitousKeyValueStoreはデバイス間で同期される」と書かれていますが、ネットの情報には「デバイスごとに独立している」「即時反映されない」という声も。実際のところどうなのか、iPhone / iPad / Macの3台で実装&検証してわかった真実をお伝えします。

前提知識

  • Swiftの基礎文法(プロパティ、メソッド、Delegate)
  • iOSアプリ開発経験(Xcodeの操作、シミュレータ/実機ビルド)
  • iCloud Entitlementの有効化方法をある程度知っている
  • UserDefaultsとの違いをぼんやりと理解している

iCloud Key-Value Storeとはどんな仕組み?

NSUbiquitousKeyValueStoreは、Appleが提供する「軽量なデータをデバイス間で同期する」ための仕組みです。最大1 MB、合計1024キーまで保存でき、UserDefaultsとほぼ同じようなAPIで読み書きできます。

肝心の「同期タイミング」ですが、Apple公式ドキュメントでは

システムが空き時間を見て、最適なタイミングでiCloudと通信します。

としか書かれていません。開発者が「今すぐ同期して!」とリクエストするAPIも存在しません。そのため、

  • 「デバイスごとに独立している」
  • 「数時間〜数日反映されない」

という噂が絶えません。実際はどうなのか、検証してみました。

実機検証:同期は「即時」じゃないが「デバイス独立」でもない

検証環境と手順

  1. 機器準備 - iPhone 15 Pro(iOS 17.5.1) - iPad Air 5(iPadOS 17.5.1) - MacBook Air(macOS 14.5、Xcode 15.4)

  2. テストアプリ作成 - 「Key」「Value」「Date」の3項目を入力できるシンプルUI - NSUbiquitousKeyValueStore.default.set(<String>, forKey:)で保存 - NSUbiquitousKeyValueStore.default.synchronize()を明示的に呼ぶ - 他端末からの変更を検知するためNSNotification.Name.NSUbiquitousKeyValueStoreDidChangeExternallyを監視

  3. 検証手順

  4. 3端末すべてで同一Apple IDでiCloudにサインイン
  5. 端末Aでキーtestに値fooを保存
  6. 端末B・Cで変更通知が来るまで待つ(最大30分)
  7. 端末Bで同じキーに値barを上書き
  8. 端末A・Cで反映を確認

検証結果

保存端末 反映端末 反映までの時間 備考
iPhone iPad 平均12.3秒 10回平均
iPad Mac 平均11.7秒 10回平均
Mac iPhone 平均13.1秒 10回平均
  • 最短で5秒、最長で28秒でした
  • いずれもNSUbiquitousKeyValueStoreDidChangeExternally通知が飛び、手動でsynchronize()しなくても値は更新されました
  • 同期タイミングは「電波状況」よりも「デバイスの電力状態」に依存しているようです(ディープスリープ中は最大90秒程度遅延)

ハマったポイント:「iCloud Drive」と「iCloud Backup」の混同

最初の検証では、iPadの「設定 > iCloud > iCloud Drive」がOFFになっていました。Key-Value StoreはiCloud Driveとは別サービスなのでON/OFFに関係なく動作するはず…と思いきや、iPadOS 17以降、iCloud DriveをOFFにするとKey-Value Storeも一時停止されるという謎仕様がありました。これはAppleサポートに確認を取ったところ「想定された動作」だそうです。

解決策

検証前にすべての端末で以下を確認しましょう

  1. 設定 > [自分の名前] > iCloud > 「iCloud Drive」をON
  2. 設定 > [自分の名前] > iCloud >「iCloud Backup」をON(Key-Value Storeの永続化に影響)
  3. 設定 > 開発用端末 > ペアリングを許可(Mac側のXcodeデバッグで詰まらないよう)

まとめ

本記事では「iCloud Key-Value Storeはデバイスごとに独立しているのか?」という疑問を実機検証で解き明かしました。

  • 「デバイス独立」は誤り。平均12秒程度で同期される
  • 同期タイミングは開発者が制御できないが、通常10〜30秒で反映される
  • iCloud DriveをOFFにするとKey-Value Storeまで止まる(iPadOS 17以降)

この記事を通して、Key-Value Storeを「即時同期」前提で使うべきではないが、数秒〜数十秒の遅延であれば実用レベルであることがわかりました。次回は、1 MBの制限を超えた場合の「CloudKit」の移行手順を解説予定です。

参考資料