iOS开发-iCloud环境配置及使用

配置iCloud

配置iCloud,首先你就先要有一个真实的苹果开发者账号,没错,就是一年688的那个。开通了之后,在Xcode中新建一个项目。然后在 TARGETS -> Capabilities -> iCloud中打开开关就可以了。

就像这样,是不是很简单啊。

image

诶,可是好像有什么地方不对,有些地方爆红了。

这是因为我们还没有给这个App ID 注册,所以接下来我们去苹果的 开发者官网 添加一个App ID,在添加的时候勾选 iCloud 服务就可以啦。

image

什么?你说你已经创建过App ID了???没关系,在管理App ID这边选择 Edit,然后在勾选iCloud也是一样的。

image

这时候回到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的[地址

image

以上就是关于配置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文档的存储功能,一些交互没有完善,但是基本的增删改查功能都已经实现了。

image

以上就是iCloud Document的简单使用。此文章仅供个人学习使用,如有不当,希望大佬指出。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容