はじめに
この記事は、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も存在しません。そのため、
- 「デバイスごとに独立している」
- 「数時間〜数日反映されない」
という噂が絶えません。実際はどうなのか、検証してみました。
実機検証:同期は「即時」じゃないが「デバイス独立」でもない
検証環境と手順
-
機器準備 - iPhone 15 Pro(iOS 17.5.1) - iPad Air 5(iPadOS 17.5.1) - MacBook Air(macOS 14.5、Xcode 15.4)
-
テストアプリ作成 - 「Key」「Value」「Date」の3項目を入力できるシンプルUI -
NSUbiquitousKeyValueStore.default.set(<String>, forKey:)で保存 -NSUbiquitousKeyValueStore.default.synchronize()を明示的に呼ぶ - 他端末からの変更を検知するためNSNotification.Name.NSUbiquitousKeyValueStoreDidChangeExternallyを監視 -
検証手順
- 3端末すべてで同一Apple IDでiCloudにサインイン
- 端末Aでキー
testに値fooを保存 - 端末B・Cで変更通知が来るまで待つ(最大30分)
- 端末Bで同じキーに値
barを上書き - 端末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サポートに確認を取ったところ「想定された動作」だそうです。
解決策
検証前にすべての端末で以下を確認しましょう
- 設定 > [自分の名前] > iCloud > 「iCloud Drive」をON
- 設定 > [自分の名前] > iCloud >「iCloud Backup」をON(Key-Value Storeの永続化に影響)
- 設定 > 開発用端末 > ペアリングを許可(Mac側のXcodeデバッグで詰まらないよう)
まとめ
本記事では「iCloud Key-Value Storeはデバイスごとに独立しているのか?」という疑問を実機検証で解き明かしました。
- 「デバイス独立」は誤り。平均12秒程度で同期される
- 同期タイミングは開発者が制御できないが、通常10〜30秒で反映される
- iCloud DriveをOFFにするとKey-Value Storeまで止まる(iPadOS 17以降)
この記事を通して、Key-Value Storeを「即時同期」前提で使うべきではないが、数秒〜数十秒の遅延であれば実用レベルであることがわかりました。次回は、1 MBの制限を超えた場合の「CloudKit」の移行手順を解説予定です。
参考資料
- Apple Developer Documentation – NSUbiquitousKeyValueStore
- iOS 17 Release Notes – Apple Developer
- Using iCloud Key-Value Store to Sync Preferences – SwiftLee
