NSUserDefaults に保存する際に自動的に iCloud にも保存してくれるライブラリ "MKiCloudSync"
MKiCloudSync を使用すると、たった1行コードを追加しておくだけで、あとは自動的に NSUserDefaults の内容を iCloud に同期してくれます。
もともとシンプルな iCloud 同期ですが、もっとシンプルになるのでとりあえず iCloud 対応したい、ちょっと試してみたい、等の場合にオススメです。
使い方
1. ソースをダウンロード
https://github.com/MugunthKumar/MKiCloudSync
2. ヘッダをインポート
#import "MKiCloudSync.h"
3. start メソッドをコール
AppDelegate の application:didFinishLaunchingWithOptions: 内で、以下のように start メソッドをコール
[MKiCloudSync start];
たったこれだけ。
「おいおい、iCloudに書き込みたいときはどうすんだ?」と思った方もいらっしゃったかもしれませんが、そこを自動化してくれてるのが MKiCloudSync なので、上記だけでいいのです。
MKiCloudSync のしくみ
簡単にいうと(実際に中身も簡単なのですが)、
NSUserDefaults の変更を監視 → 変更があれば iCloud に反映
というしくみになっています。
ソースをのぞいてみると、start メソッドをコールすると2つの通知の監視を開始していることがわかります。
if([NSUbiquitousKeyValueStore defaultStore]) { // is iCloud enabled [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateFromiCloud:) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateToiCloud:) name:NSUserDefaultsDidChangeNotification object:nil];
NSUserDefaultsDidChangeNotification は、NSUserDefaults に変更があったときに発行される通知で、この通知が発行されたときに実行される updateToiCloud: メソッドで NSUserDefaults の内容を iCloud に同期するようになっています。
また NSUbiquitousKeyValueStoreDidChangeExternallyNotification は、iCloud のキーに外部からの変更があった場合に発行される通知で、この通知を受け取ると updateFromiCloud: メソッドで iCloud の内容を NSUserDefaults に同期するようになっています。(もちろんこの間のNSUserDefaultsDidChangeNotification の監視は止めてあります)
注意点
MKiCloudSync では NSUserDefaults のキーの削除には対応していません。NSUserDefaultsDidChangeNotification の通知を受け取ったときに実行されるハンドラメソッドである updateToiCloud では、
NSDictionary *dict = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { [[NSUbiquitousKeyValueStore defaultStore] setObject:obj forKey:key]; }];
このように NSUserDefaults に存在するキーを列挙して iCloud に書き込んでいるので、NSUserDefaults に存在しなくなったキーを iCloud に書き込んではくれないのです。
これで何が困るかというと、開発中のアプリを削除して最初から動作確認しようとしても、再インストール時に NSUbiquitousKeyValueStoreDidChangeExternallyNotification 通知が発行されて iCloud からの自動同期が行われてしまい、諸々の設定値が復活してしまうという点です。
この辺りは、キーの削除への対応であれば fork して使うなり、アプリ削除への対応であればデバッグモード用に iCloud の内容をリセットする機能を追加するなりする必要があります。
たとえば僕の場合、デバッグビルド版にはこんな感じで iCloud の内容をリセットする機能をつけています。
NSUbiquitousKeyValueStore *iCloudStore = [NSUbiquitousKeyValueStore defaultStore]; NSDictionary *dict = [iCloudStore dictionaryRepresentation]; [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { [iCloudStore removeObjectForKey:key]; }];