EverBox开发笔记-3-iCloud Document Storage
原想将数据存到SQLite数据库中(沙盒中的文件),再将SQLite数据库文件上传到iCloud,于是需要学习iCloud存储文件对象的方法。
一,能直接将SQLite文件保存到iCloud吗?
答案是否定的!不能直接将SQLite文件保存到iCloud中,原因是:
在这句话的下面,Apple再次提醒开发者是否真的需要SQLite来存储数据:
SQLite stores are intended for apps that have large amounts of data to manage or want fine-grained change notifications. You do not need to read these sections if you are creating an atomic binary store.
于是就引出了Atomic Binary Store。什么是Atomic Binary Store?其实就是二进制文件,整体作为数据仓库存在。跟iCloud结合起来描述:当文件某一部分发生变化时,文件的整体(而不像SQLite那样,只有修改的内容)会被传输到iCloud。
二,在iCloud中如何存储独立文件(比如音频)
除了在iCloud Storage这一章中对Document Storage进行描述外,贴心的苹果又给我们提供教程了——Your Third iOS App
不过这个教程似乎并不对我的胃口,我只想把沙盒中的文件存到iCloud,需要时下载下来,不需要时就删除,不用修改文件,但所谓见微知著,在照猫画虎把教程中的内容重现一遍后,在这个过程中读到的知识帮我解决了这个问题,
方法是:
1,获取沙盒中文件的位置,得到一个NSURL类型指针。测试时,我在沙盒内创建了一个文件 _createdFilePath:
NSFileManager * fm = [NSFileManager defaultManager];NSArray * paths = [fm URLsForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask];NSURL * documentURL = [paths objectAtIndex:0];_createdFilePath = [documentURL URLByAppendingPathComponent:@”localfile.dat” isDirectory:NO];
2,在iCloud中创建一个路径,用于保存文件。
NSString * string = [NSString stringWithFormat:@”Created at: %@”, [[NSDate date] description]];NSFileManager * fm = [NSFileManager defaultManager];NSURL * newDocumentURL = [fm URLForUbiquityContainerIdentifier:nil];newDocumentURL = [newDocumentURL URLByAppendingPathComponent:@”directory_in_iCloud” isDirectory:YES];newDocumentURL = [newDocumentURL URLByAppendingPathComponent:@”iCloudFile.dat”];
3,将沙盒中的文件保存到iCloud中。
[fm setUbiquitous:YES itemAtURL:_createdFilePath destinationURL:newDocumentURL error:nil];
第2步和第3步不能在主线程中执行,因为iCloud相关操作可能耗时较长,为避免阻塞主线程,可以使用dispatch queue:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUUE_PRIORITY_DEFAULT), 0), ^{ 2的代码。 3的代码。});
如果需要对文件的内容进行修改,比如保存字符串对象的文件,你就需要子类化(subclass)一个UIDocument类,并重载其中的两个接口:
读数据接口:
loadFromContents: ofType: error:
写数据接口:
contentsForType: error:
对于这种需求Your Third iOS App 是个极好的例子。