配置iCloud
配置iCloud,首先你就先要有一个真实的苹果开发者账号,没错,就是一年688的那个。开通了之后,在Xcode中新建一个项目。然后在 TARGETS
-> Capabilities
-> iCloud
中打开开关就可以了。
就像这样,是不是很简单啊。
诶,可是好像有什么地方不对,有些地方爆红了。
这是因为我们还没有给这个App ID 注册,所以接下来我们去苹果的 开发者官网 添加一个App ID,在添加的时候勾选 iCloud
服务就可以啦。
什么?你说你已经创建过App ID了???没关系,在管理App ID这边选择 Edit
,然后在勾选iCloud
也是一样的。
这时候回到Xcode中在看一下,应该就已经没有爆红了吧。
什么???还有爆红??? 那你重启一下XCode试试吧。再不行,你重启一下电脑试试好了。
1、Key-value storage
在Xcode中 iCloud
下边一共有三个可以勾选的服务,其中第一个就是key-value storage
,这个也是最简单的iCloud
使用方法了,他跟NSUserDefaults
的使用方法基本一样,都是以键值对的方式存储数据。只不过处理iCloud的类为NSUbiquitousKeyValueStore
。
存储数据
存储数据的方式很简单,只要使用 setObject:forkey:
之后,使用synchronize
同步一下就可以了。
NSUbiquitousKeyValueStore *keyValueStore = [NSUbiquitousKeyValueStore defaultStore];
[keyValueStore setObject:@"test message" forKey:@"test"];
[keyValueStore synchronize];
获取数据
获取数据的方式也一样,是要使用 objectForKey
就可以了。
NSUbiquitousKeyValueStore *keyValueStore = [NSUbiquitousKeyValueStore defaultStore];
NSString *testString = [keyValueStore objectForKey:@"test"];
NSLog(@"%@",testString);
数据改变通知
看一下NSUbiquitousKeyValueStore
的头文件,我们发现他还有一个通知消息
FOUNDATION_EXPORT NSNotificationName const NSUbiquitousKeyValueStoreDidChangeExternallyNotification API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
注册这个通知,就可以在数据修改的时候接收到通知,然后做对应的处理。最好的验证方法就是在存储了数据之后直接删除掉这个app,然后再次安装,这个时候就会触发该通知。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(storeDidChange:) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:[NSUbiquitousKeyValueStore defaultStore]];
- (void)storeDidChange:(NSUbiquitousKeyValueStore *)defaultStore
{
NSLog(@"%@",defaultStore);
}
Demo
先放一下demo的[地址。
以上就是关于配置iCloud和key-value存储的简单使用,后边我们再看看其他两种服务是怎么样使用的。
2、Documents数据的使用
相较于key-value的存储类型,Documents是用来管理一些比较大的文件,比如用户创建的文档等等。
基本概念
iCloud Entitlements
在我们打开iCloud选项的时候,系统就是自动为我们添加一个 xxx.entitlements
的文件,这个东西用来保证应用的安全性,确保只有你的应用才能访问你自己创建的文档,系统也是依赖于他来区分用户的iCloud账户中每个应用的文档。
查看这个xxx.entitlements
我们会发现在他里边有这样的一个keyUbiquity Container Identifiers
,对应的value为iCloud.$(CFBundleIdentifier)
。其实这个$(CFBundleIdentifier)
就代表这你的APP ID。所以也可以看成是iCloud.com.zzr.ZZRiCloudDemo
。
NSFileManager
NSFileManager
主要是对文件的操作,我们用它来获取iCloud的存储地址。
根据我们的entitlements,通过NSFileManager
就可以获得iCloud的存储地址,在获取地址之后,我们要先判断一下获取的地址是否为空,如果这个地址为空,则说明用户的iCloud暂时不可用,接下来一切的操作都没办法进行下去。
//获取地址
+ (NSURL *)getUbiquityContauneURLWithFileName:(NSString *)fileName
{
NSURL *ubiquityURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:UbiquityContainerIdentifiers];
//验证iCloud是否可用
if(!ubiquityURL)
{
NSLog(@"尚未开启iCloud功能");
return nil;
}
NSURL *URLWithFileName = [ubiquityURL URLByAppendingPathComponent:@"Documents"];
URLWithFileName = [URLWithFileName URLByAppendingPathComponent:fileName];
return URLWithFileName;
}
UIDocument
UIDocument
主要是用于对文件内容的操作。
其实获取了文件的地址之后,我们已经可以直接对文件进行操作了,但是官方还是让我们通过UIDocument
来操作,因为当我们在对iCloud进行操作的时候,不止是只有我们自己对他进行操作,iCloud daemon
也会对iCloud操作,用UIDocument
操作能够保证存取安全。
在使用UIDocument
之前,我们新建一个类,继承于UIDocument
,并且重写两个方法:
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError * _Nullable __autoreleasing *)outError
{
self.myData = [contents copy];
return YES;
}
- (nullable id)contentsForType:(NSString *)typeName error:(NSError * _Nullable __autoreleasing *)outError
{
if(!self.myData)
{
self.myData = [[NSData alloc] init];
}
return self.myData;
}
NSMetadataQuery
NSMetadataQuery
主要用来查询数据。
增删改查
创建文档
有了之前的准备工作,创建一个文档就非常简单了,只要创建好我们要保存的文件,通过
- (void)saveToURL:(NSURL *)url forSaveOperation:(UIDocumentSaveOperation)saveOperation completionHandler:(void (^ __nullable)(BOOL success))completionHandler __TVOS_PROHIBITED;
就可以将文档上传到iCloud中了。
我们以一个txt文件作为示范。
//创建文档
+ (void)createDocument
{
NSString *fileName = @"test.txt";
NSURL *url = [iCloudHandle getUbiquityContauneURLWithFileName:fileName];
ZZRDocument *doc = [[ZZRDocument alloc] initWithFileURL:url];
NSString *docContent = @"iCloud Document 测试数据";
doc.myData = [docContent dataUsingEncoding:NSUTF8StringEncoding];
[doc saveToURL:url forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
if(success)
{
NSLog(@"创建文档成功");
}
else
{
NSLog(@"创建文档失败");
}
}];
}
修改文档
修改文档,其实就是重写文档,就是将上边创建文档中的UIDocumentSaveForCreating
改为UIDocumentSaveForOverwriting
。
//修改文档 实际上是overwrite重写
+ (void)overwriteDocument
{
NSString *fileName = @"test.txt";
NSURL *url = [iCloudHandle getUbiquityContauneURLWithFileName:fileName];
ZZRDocument *doc = [[ZZRDocument alloc] initWithFileURL:url];
NSString *docContent = @"iCloud Document 修改数据";
doc.myData = [docContent dataUsingEncoding:NSUTF8StringEncoding];
[doc saveToURL:url forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) {
if(success)
{
NSLog(@"修改文档成功");
}
else
{
NSLog(@"修改文档失败");
}
}];
}
删除文档
删除文档其实就是通过之前的地址获取到文件,然后调用remove方法即可。
//删除文档
+ (void)removeDocument
{
NSString *fileName = @"test.txt";
NSURL *url = [iCloudHandle getUbiquityContauneURLWithFileName:fileName];
NSError *error;
[[NSFileManager defaultManager] removeItemAtURL:url error:&error];
if(error)
{
NSLog(@"删除文档失败 %@",error);
}
else
{
NSLog(@"删除文档成功");
}
}
查询文档
之前讲了增加、删除、修改,好像增删改查中只剩下查询这个方法没有介绍了。查询和前边几个有点不同,他需要用到NSMetadataQuery
。
//获取最新的数据
+ (void)getNewDocument:(NSMetadataQuery *)myMetadataQuery
{
[myMetadataQuery setSearchScopes:@[NSMetadataQueryUbiquitousDocumentsScope]];
[myMetadataQuery startQuery];
}
直接调用startQuery
开始查询,iCloud就已经开始帮我们查询了,查询好之后,iCloud会通过通知来告诉我们查询到了东西。
所以我们注册两个通知
//获取最新数据完成
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(finishedGetNewDocument:) name:NSMetadataQueryDidFinishGatheringNotification object:self.myMetadataQuery];
//数据更新通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentDidChange:) name:NSMetadataQueryDidUpdateNotification object:self.myMetadataQuery];
并相应他们
- (void)finishedGetNewDocument:(NSMetadataQuery *)metadataQuery
{
NSArray *item =self.myMetadataQuery.results;
[item enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSMetadataItem *item = obj;
//获取文件名
NSString *fileName = [item valueForAttribute:NSMetadataItemFSNameKey];
//获取文件创建日期
NSDate *date = [item valueForAttribute:NSMetadataItemFSContentChangeDateKey];
NSLog(@"%@,%@",fileName,date);
ZZRDocument *doc = [[ZZRDocument alloc] initWithFileURL:[iCloudHandle getUbiquityContauneURLWithFileName:fileName]];
[doc openWithCompletionHandler:^(BOOL success) {
if(success)
{
NSLog(@"读取数据成功。");
NSString *docConten = [[NSString alloc] initWithData:doc.myData encoding:NSUTF8StringEncoding];
NSLog(@"%@",docConten);
}
}];
}];
}
- (void)documentDidChange:(NSMetadataQuery *)metadataQuery
{
NSLog(@"Document 数据更新");
}
其中
NSArray *item =self.myMetadataQuery.results;
就是查询到的内容的数组,遍历他,就可以获取到对应目录下的全部文件了。
Demo
先放一下demo的地址。
demo简单的制作了一个text文档的存储功能,一些交互没有完善,但是基本的增删改查功能都已经实现了。
以上就是iCloud Document
的简单使用。此文章仅供个人学习使用,如有不当,希望大佬指出。