iOS项目iCloud及CloudKit Dashboard运用
CloudKit是苹果推出的基于iCloud的一个云端数据存储服务.其 主要由下面两部分组成:
一个仪表web页面,用于管理公开数据的记录类型.
一组API接口,用于iCloud和设备之间的数据传递.
一:首先在XCode上面打开关于iCloud功能
1:进入对应的项目Targets 中的Capabilities 选项卡,打开关于iCloud功能;如果勾选iCloud Documents或CloudKit会自动生成一个带iCloud.开头的Containers,要配置证书支持;CloudKit Dashboard则可以直接跳转到Web配置关于iCloud的内容;而关于Steps则是配置的步骤是否都成功;

二:关于证书如何配置支持iCloud功能
1:进入苹果证书管理后台中的Identifiers里有个iCloud Containers菜单

因为实例中的Bundle Identifier的名字wjy.com.MobileProject;所以在这边创建一个iCloud.wjy.com.MobileProject的ID值;都是前面增加一个iCloud为开头;app的bundle id需要与iCloud容器相对应, iCloud容器名必须是唯一的,因为这是Cloudkit用来访问数据所使用的全局标识符。由于iCloud容器名包含bundle id,因此bundle id也必须是唯一的(这就是为何需要修改com.raywendrelich.BabiFud)。
为了让entitlements起作用,需要在App的证书、标识符与配置文件中ID的部分列出app/bundle id。这意味着标识的证书使用了设置的team id与app id,从中可得到iCloud容器的id。若已经在一个可用的开发者账号中标识了的话Xcode会自动完成这一切。不巧的是,这有时是不同步的,需要更新ID-使用iCloud功能面板修改CloudKit容器ID。否则的话需要修改info.plist文件或BabiFud.entitlements文件来确保id values与所设置的bundle id一致。
2:创建完上面的ID后,同样进行Identifiers里的App IDs,找到我们当前的App ID然后对它进行编辑

打开iCloud的功能选择,并且选择Include CloudKit support,这边这时会有一个警告出现,选择右边的Edit进行编辑

这时会有刚才创建好的那个iCloud ID可以选择绑定;选择好以后外面的警告也会消除;然后生成对应的描述文件安装后,XCode上面的步骤报错也会消除;
三:设置iCloud的数据
1:要进入CloudKit Dashboard操作有两种方式,第一种如上面第一点所说可以直接点CloudKit Dashboard进入,另一种就是进入苹果账号后台也有一个相应的菜单;

2:进入CloudKit Dashboard可以看到如下的页面

2.1 SCHEMA :
CloudKit容器的高级类:Record Types, Security Roles, 和Subscription Types,其中主要使用的是Record Types;
一个Record Type用来定义一个单独的记录(可以理解为一个数据模型),相当于存储数据的模板,和数据库的表结构类似;
2.2 PUBLIC DATA 和 PRIVATE DATA
就是你保存数据的地方,开发者可以查看所有的共享数据,但是只能看到自己的私密数据,无法看到用户的私密数据;这里没有显示PRIBATE DATA,其结构和PUBLIC DATA是一样的;
User Records 记录一些当前使用者的信息;
Default Zone :这里可以查看数据的详细信息,也是后面主要使用的;
2.3 ADMIN 主要是管理开发者团队权限的,这里不做过多介绍;
3:切回Record Type选项,点击右边栏的左上角的 "+ ",新增一个模型:

输入模型名称: 默认只有一个StringField的属性(这里暂且这么称呼吧),可以点击下面的Add Field... 新增属性列表;
同样可以选择属性的类型,如下图:

设置完成后,点击右下角的 Save按钮即可保存!这样,一个模型就建立好了;存储类型的数据:
. NSData (single bytes)
. NSDate (date and time)
. NSNumber (both Int and Double)
. NSString (or String in Swift)
. NSArray (list)
. CKReference (used to create relationships between objects)
. CLLocation (location)
. CKAsset (file)
5:回到Default Zone,中间蓝色区域的右上角的名称旁有个倒三角,这里可以选择使用(查询)哪个模型下的数据:

6:如果要存是图片字段记得选Asset类型

注意:1 Public Record ,1 Private Record,意思是:使用模型Note的有一条公共数据,一条隐私数据,由于我登陆的iCloud账号和开发者账号不一样,相当于是用户账号,所以这里是看不到那个隐私数据的
四:代码操作iCloud功能
1:首先引入CloudKit.framework系统框架,并引入命名空间#import <CloudKit/CloudKit.h> 就可以进行操作
2:首先是判断手机中的iCloud功能是否开启,如下面如果有值则表示已经开启的iCloud功能;
id cloudUrl=[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
这个方法接受一个参数, 就是要获取的容器标识。 所谓容器标识, 大多数应用只会用到一个 iCloud 容器,所以我们这里传入 nil, 就代表默认获取第一个可用的容器。这个方法内部会查找当前应用拥有的 iCloud 容器, 如果找到就会返回这个容器的 URL, 证明当前应用的 iCloud 容器可用。 如果找不到,就会返回 nil, 证明当前应用的 iCloud 不可用。
注意: iCloud 容器和你 App 文件沙盒, 在 iOS 文件系统中其实是分别存放在两个不同的地方的:
iCloud 文件路径格式 file:///private/var/mobile/Library/Mobile%20Documents/iCloud~com~xxx~aaa/Documents
App 沙盒文件路径格式 file:///var/mobile/Containers/Data/Application/3B4376B3-89B5-3342-8057-3450D4224518/Documents/
由此可见, 这也是为什么 iCloud 和 Sandbox 文件路径访问需要两套不同的方式的原因了。
3:增加一条记录,可以给它一个固定的recordID,就像数据表的主键一样,查找、更新跟删除有用;
-(void)addCloudDataWithPublic:(BOOL)isPublic recordID:(NSString *)recordID name:(NSString *)name password:(NSString *)password
{
//CloudKit给应用程序分配部分空间,用于存储数据,首先要获取这个存储空间,这里我们直接获取了默认的存储器(可以自定义存储器):
CKContainer *container=[CKContainer defaultContainer];
CKDatabase *database;
if (isPublic) {
database=container.publicCloudDatabase; //公共数据
}
else
{
database=container.privateCloudDatabase;//隐藏数据
} //创建主键ID 这个ID可以到时查找有用到
CKRecordID *noteId=[[CKRecordID alloc]initWithRecordName:recordID];
//创建CKRecord 保存数据
CKRecord *noteRecord = [[CKRecord alloc]initWithRecordType:@"User" recordID:noteId]; //设置数据
[noteRecord setObject:name forKey:@"name"];
[noteRecord setObject:password forKey:@"password"]; //保存操作
[database saveRecord:noteRecord completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
if (!error) {
[self showAlertMessage:@"保存成功"];
}
}];
}
4:假如要保存带有图片的字段,需要用到CKAsset,他的初始化需要一个URL,所以这里,我先把图片数据保存到本地沙盒,生成一个URL,然后再去创建CKAsset:
//增加带图片的提交 图片的保存,需要用到CKAsset,他的初始化需要一个URL,所以这里,我先把图片数据保存到本地沙盒,生成一个URL,然后再去创建CKAsset:
-(void)saveImageDataWithPublic:(BOOL)isPublic recordID:(NSString *)recordID name:(NSString *)name password:(NSString *)password
{
//保存图片 图片的保存,需要用到CKAsset,他的初始化需要一个URL,所以这里,我先把图片数据保存到本地沙盒,生成一个URL,然后再去创建CKAsset:
UIImage *image=[UIImage imageNamed:@"icloudImage"];
NSData *imageData = UIImagePNGRepresentation(image);
if (imageData == nil) {
imageData = UIImageJPEGRepresentation(image, 0.6);
}
NSString *tempPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/imagesTemp"];
NSFileManager *manager = [NSFileManager defaultManager];
if (![manager fileExistsAtPath:tempPath]) { [manager createDirectoryAtPath:tempPath withIntermediateDirectories:YES attributes:nil error:nil];
} NSString *filePath = [NSString stringWithFormat:@"%@/%@",tempPath,@"iCloudImage"];
NSURL *url = [NSURL fileURLWithPath:filePath];
[imageData writeToURL:url atomically:YES]; CKAsset *asset = [[CKAsset alloc]initWithFileURL:url]; //与iCloud进行交互
CKContainer *container=[CKContainer defaultContainer];
CKDatabase *database;
if (isPublic) {
database=container.publicCloudDatabase; //公共数据
}
else
{
database=container.privateCloudDatabase;//隐藏数据
} //创建主键ID 这个ID可以到时查找有用到
CKRecordID *noteId=[[CKRecordID alloc]initWithRecordName:recordID];
//创建CKRecord 保存数据
CKRecord *noteRecord = [[CKRecord alloc]initWithRecordType:@"User" recordID:noteId]; //设置数据
[noteRecord setObject:name forKey:@"name"];
[noteRecord setObject:password forKey:@"password"];
[noteRecord setObject:asset forKey:@"userImage"]; //保存操作
[database saveRecord:noteRecord completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
if (!error) {
[self showAlertMessage:@"保存成功"];
}
}];
}
5:查找单条记录的功能,通过recordID进行
//查找单条记录
-(void)searchRecordWithRecordID:(NSString *)recordID withFormPublic:(BOOL)isPublic
{
//获得指定的ID
CKRecordID *noteId=[[CKRecordID alloc]initWithRecordName:recordID]; //获得容器
CKContainer *container=[CKContainer defaultContainer]; //获得数据的类型 是公有还是私有
CKDatabase *database;
if (isPublic) {
database=container.publicCloudDatabase;
}
else
{
database=container.privateCloudDatabase;
} __weak typeof(self)weakSelf = self;
//查找操作
[database fetchRecordWithID:noteId completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
NSString *message=[NSString stringWithFormat:@"获得RecordID为%@ 的数据:%@,%@",recordID,[record objectForKey:@"name"],[record objectForKey:@"password"]];
[weakSelf showAlertMessage:message];
}];
}
6:查询多条记录的功能,用到的谓词进行
//查找多条记录(可以用谓词进行)
-(void)searchRecordWithFormPublic:(BOOL)isPublic withRecordTypeName:(NSString *)recordTypeName
{
CKContainer *container=[CKContainer defaultContainer];
//获得数据的类型 是公有还是私有
CKDatabase *database;
if (isPublic) {
database=container.publicCloudDatabase;
}
else
{
database=container.privateCloudDatabase;
} NSPredicate *predicate=[NSPredicate predicateWithValue:YES];
CKQuery *query=[[CKQuery alloc]initWithRecordType:recordTypeName predicate:predicate]; __weak typeof(self)weakSelf = self;
[database performQuery:query inZoneWithID:nil completionHandler:^(NSArray<CKRecord *> * _Nullable results, NSError * _Nullable error) {
[weakSelf showAlertMessage:[NSString stringWithFormat:@"%@",results]];
}];
}
7:更新一条记录首先要查找出该条记录,再对它进行修改,如果对应的键值存在进修改其值,如果键值不存在则增加新的类型字段;
//更新一条记录 首先要查找出这一条 然后再对它进行修改
-(void)updateRecordWithFormPublic:(BOOL)isPublic withRecordTypeName:(NSString *)recordTypeName withRecordID:(NSString *)recordID
{
//获得指定的ID
CKRecordID *noteId=[[CKRecordID alloc]initWithRecordName:recordID]; //获得容器
CKContainer *container=[CKContainer defaultContainer]; //获得数据的类型 是公有还是私有
CKDatabase *database;
if (isPublic) {
database=container.publicCloudDatabase;
}
else
{
database=container.privateCloudDatabase;
} __weak typeof(self)weakSelf = self;
//查找操作
[database fetchRecordWithID:noteId completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
if (!error) { //对原有的健值进行修改
[record setObject:@"aa123456789" forKey:@"password"];
//如果健值不存在 则会增加一个
[record setObject:@"男" forKey:@"gender"]; [database saveRecord:record completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
if (!error) {
[weakSelf showAlertMessage:@"修改保存成功"];
}
else
{
[weakSelf showAlertMessage:[NSString stringWithFormat:@"出错误 :%@",error]];
}
}]; }
}];
}
8:删除一条记录
//删除记录
-(void)deleteRecordWithFormPublic:(BOOL)isPublic withRecordID:(NSString *)recordID
{
//获得指定的ID
CKRecordID *noteId=[[CKRecordID alloc]initWithRecordName:recordID]; //获得容器
CKContainer *container=[CKContainer defaultContainer]; //获得数据的类型 是公有还是私有
CKDatabase *database;
if (isPublic) {
database=container.publicCloudDatabase;
}
else
{
database=container.privateCloudDatabase;
} __weak typeof(self)weakSelf = self;
[database deleteRecordWithID:noteId completionHandler:^(CKRecordID * _Nullable recordID, NSError * _Nullable error) {
if (!error) {
[weakSelf showAlertMessage:@"删除成功"];
return;
}
[weakSelf showAlertMessage:[NSString stringWithFormat:@"删除失败 %@",error]];
}]; }
五:操作实例
编写一个关于在同一台手机上免登录的实例,主要原理是通过获取手机设备唯一码,然后通过iCloud保存到云端,在删除APP后再安装后就可以直接从云端获得用户跟密码;会不断完善此实例,如果感兴趣可以点星并关注,会接着编写关于iCloud关于文件的同步功能;注意证书可以换成自个的,步骤如上:
源代码地址:https://github.com/wujunyang/iCloudProject
最近有个妹子弄的一个关于扩大眼界跟内含的订阅号,每天都会更新一些深度内容,在这里如果你感兴趣也可以关注一下(嘿对美女跟知识感兴趣),当然可以关注后输入:github 会有我的微信号,如果有问题你也可以在那找到我;当然不感兴趣无视此信息;

iOS项目iCloud及CloudKit Dashboard运用的更多相关文章
- ios项目里扒出来的json文件
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000 } p.p2 { margin: 0.0px 0. ...
- 上传IOS项目和版本更新流程图
上传IOS项目和版本更新流程图 必备IDP证书和distribution证书(第一个证书是真机部署测试时用到的,后者证书是发布时需要用到的,缺一不可). 我就说说接下来应该做的流程.在你保证拥有以上两 ...
- 开源 iOS 项目分类索引大全 - 待整理
开源 iOS 项目分类索引大全 GitHub 上大概600个开源 iOS 项目的分类和介绍,对于你挑选和使用开源项目应该有帮助 系统基础库 Category/Util sstoolkit 一套Cate ...
- 现有iOS项目集成React Native过程记录
在<Mac系统下React Native环境搭建>配置了RN的开发环境,然后,本文记录在现有iOS项目集成React Native的过程,官方推荐使用Cocoapods,项目一开始也是使用 ...
- iOS项目的本地化处理(多国语言)
项目的本地化就是:iOS系统在不同语言环境下自动切换语言,从而实现一个app发布到全世界各个国家的AppStore上. 我们不仅仅需要在iOS项目中做本地化处理,在上架iOS APP的时候,也需要做对 ...
- 在Xcode 6 beta里编译Cocos2d-x iOS项目时失败
转载 在Xcode 6 beta里编译Cocos2d-x iOS项目时可能会失败,提示如下错误: Undefined symbols for architecture i386: "_fwr ...
- phonegap创建的ios项目推送消息出现闪退现象
使用phonegap创建的ios项目,推送消息时,当程序在前台运行或者在后台运行状态下,推送消息过来,可以解析并且跳转: 但是在程序从后台退出的状态下,当消息推送过来的时候,点击通知栏,打开程序,程序 ...
- MVVM 模式下iOS项目目录结构详细说明
➠更多技术干货请戳:听云博客 我们在做项目的时候,会经常用到各种设计模式,最常见的要数 MVC (模型,视图,控制器)了.但是,今天我们要说的是另一种设计模式——MVVM. 所以 MVVM 到底是什么 ...
- WinObjc - 使用iOS项目生成通用Windows应用
Github上一周年的WinObjc项目最近发布了预览版本,终于等到了这一天.WinObjc项目就是Build 2015大会上微软宣布的Project IslandWood项目,致力于将iOS应用快速 ...
随机推荐
- 机器指令翻译成 JavaScript —— 终极目标
上一篇,我们顺利将 6502 指令翻译成 C 代码,并演示了一个案例. 现在,我们来完成最后的目标 -- 转换成 JavaScript. 中间码输出 我们之所以选择 C,就是为了使用 LLVM.现在来 ...
- .NET跨平台:在Ubuntu上用自己编译的dnx运行ASP.NET 5示例程序
在 Linux Ubuntu 上成功编译 dnx 之后,会在 artifacts/build/ 文件夹中生成 dnx-coreclr-linux-x64/ 与 dnx-mono/ 这2个文件夹,前者是 ...
- SVG:linearGradient渐变在直线上失效的问题解决方案
SVG开发里有个较为少见的问题. 对x1=x2或者y1=y2的直线(line以及path),比如: <path d="M200,10 200,100" stroke=&quo ...
- Nova PhoneGap框架 总结
Nova PhoneGap Framework 是完全针对PhoneGap应用程序量身定做的,在这个框架下开发的应用程序很容易实现高质量的代码,很容易让程序拥有很好的性能和用户体验. 在经历了多个项目 ...
- 让tomcat支持中文cookie
这的确是一个不正常的需求,按照规范,开发者需要将cookie进行编码,因为tomcat不支持中文cookie. 但有时候,你不得不面对这样的情况,比如请求是由他人开发的软件,比如,浏览器控件发出的. ...
- 你可能没注意的CSS单位
扶今追昔 CSS中的单位我们经常用到px.pt.em.百分比,px和pt不用多说 em em是相对单位,参考物是父元素的font-size,具有继承的特点 如果字体大小是16px(浏览器的默认值),那 ...
- Html5 快速排序演示
快速排序(Quicksort)是对冒泡排序的一种改进.快速排序由C. A. R. Hoare在1962年提出. 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另 ...
- iOS-----正则表达式的基础语法
正则表达式简单语法总结 一.什么是正则表达式 从概念上来说,正则表达式也是一门小巧而精炼的语言,它可以用来简化检索特定的字符串,替换特定字符等功能,有许多开发语言工具,都内嵌支持正则表达式.那么一个正 ...
- sublime text 插件
html-css-js prettify html5 anaconda pretty json JavaScript Completions SqlBeautifier Emmet Css Snipp ...
- 大数据时代下的SQL Server第三方负载均衡方案----Moebius测试
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 架构原理(Architecture) 测试环境(Environment) 安装Moebius( ...