3.1 iCloud入门
- iCloud的目标:不是将内容存储在云端,从而释放设备本地的空间。与之相反,iCloud是对本地内容的一个镜像,应用的数据发生了改变,这些改变会被推送到云端,二iCloud会与所有连接上的设备进行同步,将这些修改更新到本地数据库中,保证每个设备都具有同样的本地内容。
- 使用场景:只用于存储用户产生的内容(文档、图像、档案、计划等)
还提供了一个轻量级的键值对存储(与NSUserDefaults类似)64k限制,可以存储用户偏好设置。 - 使用步骤:在官网上开启iCloud;添加必要的iCloud授权。
- iCloud存储容器一个App ID:H37HMHGFIU.com.anythingsimple.iCloudDemo对应的存储泛存容器为:
[iCloud]/H37HMHGFIU/com/anythingsimple/iCloudDemo
如果是iOS,Mac OS X通用的App ID使用:
com.anythingsimple.iCloudDemo.MacOSX
这样每个应用存储都在iCloudDemo文件下,可以访问公有内容同时有自己私有的文件夹。
3.2 键值对存储
-
使用键值对泛存
//检查iCloud是否可用 NSUbiquitousKeyValueStor
e *store; store=[NSUbiquitousKeyValueStor e defaultStore]; if (![store synchronize]) { NSLog(@"iCloud is Unavailable"); } -
添加和删除对象
用法与NSUserDefaults类似,调用时把对象调入内存,然后用synchronize将修改提交到磁盘或者云端。不同之处在于使用NSUbiquitousKeyValueStore时iCloud还会通知其他设备发生了这些改动。 //提交修改 NSUbiquitousKeyValueStor
e *store; store=[NSUbiquitousKeyValueStor e defaultStore]; [store setObject:favorites forKey:@"favorites"]; if (![store synchronize]) { NSLog(@"can not synchronize favorites"); -
对变更通知做出响应
//注册通知 if(iCloudSyncIfAvailable){ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(persistentStoreDidChange
:) name:NSUbiquitousKeyValueStor eDidChangeExternallyNoti fication object:coordinator]; } //收到通知的响应,注意:这里的代码使用受控对象上下文的mergeChangesFromContextD idSaveNotification的 //方法,和core data交互。本节中键值对存储需从notification中提取变化内容以及原因,代码略 - (void)persistentStoreDidChange :(NSNotification*)notification{ NSLog(@"Change Detected!"); [__managedObjectContext performBlockAndWait:^(void){ [__managedObjectContext mergeChangesFromContextD idSaveNotification:notification]; }]; }
3.3 对Core Data进行同步
- 确认iCloud是否可用
-
设置iCloud对持久化存储进行同步
#define UBIQUITY_CONTAINER_IDENTIFIER @"[TEAM_ID].com.mycompany.myapp" #define UBIQUITY_CONTENT_NAME_KEY @"com.mycompany.myapp.CoreData" // Set up persistent Store Coordinator __persistentStoreCoordinat
or = [[NSPersistentStoreCoordin ator alloc] initWithManagedObjectMod el:[self managedObjectModel]]; // 1.设置数据库文件URL NSURL *storeURL = [[self applicationDocumentsDire ctory] URLByAppendingPathCompon ent:[NSString stringWithFormat:@"%@.sqlite",ManagedObjectModelFileNa me]]; NSDictionary *options = nil; // 2.设置iCloud选项字典 if(iCloudSyncIfAvailable && _iCloudAvailable){ [[NSBundle mainBundle] bundleIdentifier]; NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *contentURL = [fileManager URLForUbiquityContainerI dentifier:UBIQUITY_CONTAINER_IDENTIFIER]; NSDictionary *options = [NSDictionary dictionaryWithObjectsAnd Keys: UBIQUITY_CONTENT_NAME_KEY, NSPersistentStoreUbiquit ousContentNameKey, contentURL, NSPersistentStoreUbiquit ousContentURLKey, nil]; } else if(!_iCloudAvailable){ NSLog(@"Attempted to set up iCloud Core Data Stack, but iCloud is unvailable"); } // 3.创建持久化存储Add the persistent store to the persistent store coordinator NSError *error = nil; if (![__persistentStoreCoordinat or addPersistentStoreWithTy pe:NSSQLiteStoreType configuration:nil URL:storeURL //1.数据库文件URL options:options //2.iCloud选项字典 error:&error]){ // Handle the error NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } -
Core Data持久化存储的变更通知
代码见上,不同之处:- 注册通知的key为NSUbiquitousKeyValueStor
eDidChangeExternallyNoti fication - 处理通知使用mergeChangesFromContextD
idSaveNotification -
注意这里执行需要用performBlock因为:
1) 通知在main queue之外出发但是执行需要在 main queue
2) 创建NSManagedObjectContext的时候用的是NSMainQueueConcurrencyType所以它执行的代码都在main queue. NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyTy
pe];
- 注册通知的key为NSUbiquitousKeyValueStor