iCloud(二)保存key value数据到iCloud

40 篇文章 0 订阅
3 篇文章 0 订阅

准备:

1. Add iCloud in iTunes connect. And create a new provision file and entitlements.
    具体请参考refs 1.
2. Only devices support iCloud.
    Simulator不支持iCloud.
3. Add your account in your device. If you do not do this, you can use iCloud functionalities.
    在Setting->iCloud中输入iTuns Connect的帐号,否则在程序中将接收不到iCloud的消息。

什么时候该用Key-Value来存储?

适合于数据量不超过1M的数据。比如preferences, settings, simple app state.

背景:

什么是Ubiquity Container?

To save data to iCloud, your app places the data in special file system locations known as ubiquity containers. Aubiquity container serves as the local representation of corresponding iCloud storage. It is outside of your app’s sandbox container, as shown in Figure 1-1.

Figure 1-1  Your app’s main ubiquity container in context

程序中并不是直接将数据存到远程的iCloud服务器,而是存到Ubiquity Container中,Ubiquity Container并不包含在App的地址空间中。Ubiquity Container会在适当的时候自动与远程的iCloud服务器同步。你的程序应该要实现监听Ubiquity Container的代码,一旦Ubiquity Container更新数据,你就作出相应的动作。所有与Ubiquity Container的操作,包括上传数据到Ubiquity Container,从Ubiquity Container下载数据,处理conflict等等的动作,你都需要手动去处理。

Check iCloud is avaiable:

- (void)initializeiCloudAccessWithCompletion:(void(^)(BOOL available))completion
{
    // obtain the url to your ubiquity containter.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
        self.iCloudRootURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
        if (self.iCloudRootURL != nil)
        {
            // write the container.
            dispatch_async(dispatch_get_main_queue(), ^(void) {
                // On main thread, update UI and state as appropriate.
                NSLog(@"iCloud access: %@", self.iCloudRootURL);                
                completion(TRUE);
            });
        }
        else
        {
            dispatch_async(dispatch_get_main_queue(), ^(void) {
                // On main thread, update UI and state as appropriate.
                NSLog(@"iCloud not available.");
                completion(FALSE);
            });
        }
    });
}
If iCloud is available, self.iCloudRootURL will be the NSURL of the Ubiquity Container path.

Designing for Key-Value Data in iCloud

Save data to Ubiquity Container:

NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:
                         @"wang",   @"name",
                         @(10),       @"age",     nil];
    [[NSUbiquitousKeyValueStore defaultStore] setDictionary:dic forKey:@"iCloud_Save_Data"];
    [[NSUbiquitousKeyValueStore defaultStore] synchronize];

Detect the changing of Ubiquity Container:

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyValueStoreDidChange:)
                                                 name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
                                               object:[NSUbiquitousKeyValueStore defaultStore]];
    // get changes that might have happened while this instance of your app wasn't running.
    // Up to date the key-value store.
    [[NSUbiquitousKeyValueStore defaultStore] synchronize];

If there is data changed in iCloud, the keyValueStoreDidChange will be called
- (void)keyValueStoreDidChange:(NSNotification*)notification
{
    NSDictionary *userInfo = [notification userInfo];
    NSNumber *reason = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey];
    if (reason)
    {
        NSInteger reasonValue = [reason integerValue];
        NSLog(@"storeChanged with reason %d", reasonValue);
        
        // NSUbiquitousKeyValueStoreServerChange:
        //      this value indicates that the key-value store has changed in the cloud most likely because another device has sent a new value.
        // NSUbiquitousKeyValueStoreInitialSyncChange:
        //      this value occurs the first time the app runs and has yet to be synced with iCloud.
        if ((reasonValue == NSUbiquitousKeyValueStoreServerChange) ||
            (reasonValue == NSUbiquitousKeyValueStoreInitialSyncChange))
        {    
            NSArray *keys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];
            NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
            for (NSString *key in keys)
            {
                id value = [store objectForKey:key];
                NSLog(@"storeChanged updated value for %@, %@", key, value);
                // Test. Save all to userDefaults.
                [[NSUserDefaults standardUserDefaults] setValue:value forKey:key];
            }
        }
    }
}

数据大小的限制:

The total space available in your app’s iCloud key-value storage is 1 MB per user. The maximum number of keys you can specify is 1024, and the size limit for each value associated with a key is 1 MB. For example, if you store a single large value of exactly 1 MB for a single key, that fully consumes your quota for a given user of your app. If you store 1 KB of data for each key, you can use 1,000 key-value pairs.

The maximum length for a key string is 64 bytes using UTF8 encoding. The data size of your cumulative key strings does not count against your 1 MB total quota for iCloud key-value storage; rather, your key strings (which at maximum consume 64 KB) count against a user’s total iCloud allotment.

If your app has exceeded its quota in key-value storage, the iCloud key-value store posts theNSUbiquitousKeyValueStoreDidChangeExternallyNotification notification with a value ofNSUbiquitousKeyValueStoreQuotaViolationChange in its user info dictionary.

For more on how to use iCloud key-value storage in your app, see “Storing Preferences in iCloud” in Preferences and Settings Programming Guide, and refer to NSUbiquitousKeyValueStore Class Reference.

怎么样测试:

首先,去Setting->iCloud,输入你的iTune帐号,然后进入Storage&Backup->开启iCloud Backup,在Manage Storage中保证你要测试的app是在开启状态。
1. 如果你的App已经发布,那么到Setting->General->Reset->Reset All Settings. (这会清除所有设置,自动重新启动后,选择“restore from iCloud”).
2. 如果你的App尚未发布,则在两台设备上装上同一版本的App。试着在一台device上改变iCloud的数据,看另一台device是否会自动更新。

Refs:
1. About Your Third iOS App
2. iCloud design guide

以上。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值