iOS开发 - OC - 苹果为大家提供的后台:CloudKit 的简单使用
一、什么是cloudKit
移动开发中,网络请求数据是日常中用到的,我们习惯把一些用户改动的数据存在服务器,以便下次请求使用。或者开发者方通过服务器将编辑的数据发送给用户。但是这一切都建立在我们的APP拥有自己的服务器之上。如果没有服务器的情况下我们的某些开发就变得很难进行,比如,公司没有服务器,确需要你做出一个用户系统,这显然令人头痛,因为这几乎是一个不可能完成的任务(有人说,扯淡吧,公司会没有服务器? 呵呵,我公司就没有啊)。然而苹果提供了一些便利,虽然不能完全替代后端,但是在一定程度上可以解决数据的云端存储需求,没错就是本文要讲的:CloudKit。每个开发者在使用CloudKit之后,苹果会为其提供一个不小的dashboard作为云端数据的存储地,CloudKit 提供了一套API用于在dashboard中存取数据。简直太方便了啊有米有。
关于CloudKit的详细说明,我建议大家看看这里。
二、如何使用cloudKit
使用之前,我们先了解下关于CloudKit的一些基本数据类型。
CloudKit 基础对象类型
CloudKit 的基础对象类型有 7 种。这些对象类型可能和你在其他编程领域了解的类似对象类型稍有差别。
CKContainer: Containers 就像应用运行的沙盒一样,一个应用只能访问自己沙盒中的内容而不能访问其他应用的。Containers 就是最外层容器,每个应用有且仅有一个属于自己的 container。(事实上,经过开发者授权配置 CloudKit Dashboard 之后,一个应用也可以访问其他应用的 container。)CKDatabase: Database 即数据库,私有数据库用来存储敏感信息,比如说用户的性别年龄等,用户只能访问自己的私有数据库。应用也有一个公开的数据库来存储公共信息,例如你在构建一个根据地理位置签到的应用,那么地理位置信息就应该存储在公共数据库里以便所有用户都能访问到。CKRecord: 即数据库中的一条数据记录。CloudKit 使用 record 通过 k/v 结构来存储结构化数据。关于键值存储,目前值的架构支持 NSString、NSNumber、NSData、NSDate、CLLocation,和 CKReference、CKAsset,以及存储以上数据类型的数组。CKRecordZone: Record 不是以零散的方式存在于 database 之中的,它们位于 record zones 里。每个应用都有一个 default record zone,你也可以有自定义的 record zone。CKRecordIdentifier: 是一条 record 的唯一标识,用于确定该 record 在数据库中的唯一位置。CKReference: Reference 很像 RDBMS 中的引用关系。还是以地理位置签到应用为例,每个地理位置可以包含很多用户在该位置的签到,那么位置与签到之间就形成了这样一种包含式的从属关系。CKAsset: 即资源文件,例如二进制文件。还是以签到应用为例,用户签到时可能还包含一张照片,那么这张照片就会以 asset 形式存储起来。
本文就一个简单的例子说说使用cloudKit。假如我们需要做一个用户信息的存储系统。
使用CloudKit 的环境配置
在使用CloudKit之前,我们需要先在Xcode 中做一些配置。 (本文基于Xcode8)
- 在target -> capabilities 中找到 iColod选项。

- 打开iCloud的控制开关。
- 在展开的框中做如下设置

其中在containers中的 “ cloudKit dashBoard ”按钮可以直接进入到我们在icloud上的存储空间。 这里要确保APP中使用的开发者账号是实际存在的 。进入网页之后登录开发者账号登录。

登录成功会出现这个画面:

这里我已经存了一部分数据。 存进去之后还是很直观的,但是看不到存储的属性对应的内容,我也还在研究中。
使用CloudHit 保存数据
如果我们需要保存一个包含了用户的 账户、密码、用户名字、电话号码、邮箱、用户头像等数据的对象。 我们创建一个用户的属性类 UserInfoModel。
#import <Foundation/Foundation.h> @interface UserInfoModel : NSObject /** 账户名称 */
@property (nonatomic,strong)NSString *userAccout; /** 用户名字 */
@property (nonatomic,strong) NSString *userName; /** 用户头像 */
@property (nonatomic,strong) UIImage *userAvtar; /** 用户手机号码 */
@property (nonatomic,strong) NSString *userPhoneNum; /** 用户邮箱号 */
@property (nonatomic,strong) NSString *userEmail; /** 用户密码 */
@property (nonatomic,strong) NSString *userPassword; @end
在保存数据之前,我们为了之后方便查询,可以将某一项作为唯一标示(这要求标示不会经常被修改),比如在这里我们选择账户名,当然你也可以选择其他任意的字符,关键是之后的查找要有依据。 接下来就开始进行保存了。
- (void)saveWithModel:(UserInfoModel*)userInfoModel{
//因为账户名不变的 以帐户名做微ID最好不过了
CKRecordID *postrecordID = [[CKRecordID alloc]initWithRecordName:userInfoModel.userAccout];
CKRecord *postRecrod = [[CKRecord alloc] initWithRecordType:userInfoModel.userAccout recordID:postrecordID];
//将用户类的属性和属性值打包成一个字典 其中属性对应key 属性值对应Value 因为属性中有一栏是图片类,CloudKit不支持直接对图片进行保存,但是可以转换成NSdata,这洋就可以进行保存了. 这里说明一下 cloudKit的提交 只接受NSString、NSNumber、NSData、CLLocation,和 CKReference、CKAsset 等直接的存储, 其它的需要
NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
NSMutableArray *propArr = [self getAllProp:[userInfoModel class]]; //这里使用getAllProp 在下面贴出
for (NSString *prop in propArr) { if([[userInfoModel valueForKey:prop] isKindOfClass:[UIImage class]]){
// 图片特殊情况另外处理 如果实别的不符合存储的也同样需要处理
UIImage *image = [userInfoModel valueForKey:prop];
postRecrod[prop] = [NSData dataWithData:UIImagePNGRepresentation(image)]; //record可以像字典一样进行数据的收纳
}else{
postRecrod[prop] = [userInfoModel valueForKey:prop];
}
}
//用户信息 提交到 云
[[[CKContainer defaultContainer] privateCloudDatabase] saveRecord:postRecrod completionHandler:^(CKRecord *savedPlace, NSError *error) {
if(savedPlace){
DLog(@"%@",savedPlace); //成功 打印存储的内容
}else{
DLog(@"%@",error); //失败 打印错误
}
}];
}
- (NSMutableArray *)getAllProp:(Class)cls{
// 获取当前类的所有属性
unsigned int count;// 记录属性个数
objc_property_t *properties = class_copyPropertyList(cls, &count);
// 遍历
NSMutableArray *mArray = [NSMutableArray array];
for (int i = ; i < count; i++) {
// objc_property_t 属性类型
objc_property_t property = properties[i];
// 获取属性的名称 C语言字符串
const char *cName = property_getName(property);
// 转换为Objective C 字符串
NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
[mArray addObject:name];
}
return mArray;
}
使用CloudHit 查询数据
- (void )cloudGetUserInfoWithUseraccout:(NSString *)userAccout Succeed:(void(^)(UserInfoModel* ))succeed failed:(void(^)(NSError *))failed{
UserInfoModel *model = [[UserInfoModel alloc]init];
if(userAccout){
CKRecordID *postrecordID = [[CKRecordID alloc]initWithRecordName:userAccout];
[[[CKContainer defaultContainer] privateCloudDatabase] fetchRecordWithID:postrecordID completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
// handle errors here
if(error){
if(failed){
failed(error);
}
}else{ //说明查询成功
if(succeed){
//已经获取到了存入的数据, 并经过转换存入了字典 dic 将字典中的键值对赋给一个类对应的属性 同理因为其中有一个图片 所以需要做一个NSdata的转换
NSMutableArray *mArray = [self getAllProp:[model class]];
for (NSString *prop in mArray) { //这里如果不是在后台人为添加的数据 不会出现没有对应的属性的情况 但是为了保险起见。在UserInfoModel 重写 setVale:forUndefinedKey方法
id info = [record valueForKey:prop];
if(![info isKindOfClass:[NSData class]]){
// [model setValue:[dic valueForKey:prop] forKey:prop];
[model setValue:record[prop] forKey:prop];
}else{
UIImage *image = [UIImage imageWithData:info];
[model setValue:image forKey:prop];
}
}
succeed(model); //回调获取到的模型
}
}
} ];
}
}
使用CloudHit 删除数据
- (void)cloudDeleteModelWithModel:(UserInfoModel *)userInfoModel{
//之前也说了在存储的时候, 我们操纵cloud上的数据都是通过record ID来实现的, 所以record ID的名字应该是一个不经常改变的属性, 这里用的就是用户的账户名
CKRecordID *postrecordID = [[CKRecordID alloc]initWithRecordName:userInfoModel.userAccout];
[[[CKContainer defaultContainer] privateCloudDatabase] deleteRecordWithID:postrecordID completionHandler:^(CKRecordID * _Nullable recordID, NSError * _Nullable error) {
if(!error){
//删除成功
}else{
DLog(@"删除失败%@",error); //打印错误
}
}];
}
以上就是cloudKit的简单使用。通过这个,当需要存储一些比较简单的数据还是可以满足的。
PS:我也刚开始用,发现了一个小问题, 单次存储的数据不能太大(大小没有测试,大概是2M左右吧),不然会提示失败。 所以有的数据过大,可能需要经过拆分,或者图片过大需要经过压缩才能进行存储。
iOS开发 - OC - 苹果为大家提供的后台:CloudKit 的简单使用的更多相关文章
- 李洪强iOS开发之苹果企业开发者账号申请流程
李洪强iOS开发之苹果企业开发者账号申请流程 一. 开发者账号类型选择 邓白氏码 DUNS number,是Data Universal Numbering System的缩写,是一个独一无二的9位数 ...
- 李洪强iOS开发之苹果使用预览截图
李洪强iOS开发之苹果使用预览截图 01 在预览的图片中选中你要截得区域 02 - command + C 03 - Command + N 04 - Command + S (保存)
- iOS开发OC基础:Xcode中常见英文总结,OC常见英文错误
在开发的过程中难免会遇到很多的错误,可是当看到系统给出的英文时,又不知道是什么意思.所以这篇文章总结了Xcode中常见的一些英文单词及词组,可以帮助初学的人快速了解给出的提示.多练习,就肯定能基本掌握 ...
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
本文转自 :http://www.cnblogs.com/wendingding/p/3761730.html ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布 ...
- iOS开发UI篇—Date Picker和UITool Bar控件简单介绍
iOS开发UI篇—Date Picker和UITool Bar控件简单介绍 一.Date Picker控件 1.简单介绍: Date Picker显示时间的控件 有默认宽高,不用设置数据源和代理 如何 ...
- iOS开发UI篇—使用picker View控件完成一个简单的选餐应用
iOS开发UI篇—使用picker View控件完成一个简单的选餐应用 一.实现效果 说明:点击随机按钮,能够自动选取,下方数据自动刷新. 二.实现思路 1.picker view的有默认高度为162 ...
- iOS开发——OC篇&消息传递机制(KVO/NOtification/Block/代理/Target-Action)
iOS开发中消息传递机制(KVO/NOtification/Block/代理/Target-Action) 今晚看到了一篇好的文章,所以就搬过来了,方便自己以后学习 虽然这一期的主题是关于Fou ...
- iOS开发——OC篇&常用关键字的使用与区别
copy,assign,strong,retain,weak,readonly,readwrite,nonatomic,atomic,unsafe_unretained的使用与区别 最近在学习iOS的 ...
- iOS开发——OC篇&OC高级语法
iOS开发高级语法之分类,拓展,协议,代码块详解 一:分类 什么是分类Category? 分类就是类的补充和扩展部分 补充和扩展的每个部分就是分类 分类本质上是类的一部分 分类的定义 分类也是以代码的 ...
随机推荐
- 关于Kean博客的学习
由于我从事设计行业,使用Autocad进行绘图是一件单调但是拥有乐趣的工作. 大约在一年前,接触到了CAD的二次开发的内容,它使我感到新奇,并且决定花时间来研究相关的知识.这时我在网上浏览到了Kean ...
- IIS错误:在唯一密钥属性 fileExtension=".url"时,无法添加类型为“mimeMap”的重复集合项
代码可以运行,但没有加载上样式,后来在IIS点击MIME类型时报错了 查看web.config中 <staticContent> <mimeMap fileExtension=&qu ...
- JS实现HashMap
/** * ********* 操作实例 ************** * var map = new HashMap(); * map.put("key1","Valu ...
- 数论 UVAlive 2889
这是一道考察回文数的题目,要求你输出第k个回文数.在做题的过程中,可以发现回文数的分布的规律:一位数:9个,二位数:9个,三位数:90个,四位数:90个,五位数:900个,六位数:900个……. #i ...
- Linear Algebra lecture1 note
Professor: Gilbert Strang Text: Introduction to Linear Algebra http://web.mit.edu/18.06 Lecture 1 ...
- 初遇 dotcloud
逛园子的时候看到新浪SAE,正学习建站呢,好东西.(论环境的影响...) 不过发现新浪SAE只支持 Python2,我更喜欢 Python3 e...找找其他的,发现了 dotcloud,遂试试,下面 ...
- NIO NIO.2
An NIO.2 primer, Part 1: The asynchronous channel APIs http://blog.arganzheng.me/posts/java-network- ...
- Qt中数据模块学习
QtSql模块 驱动类型和数据库:不同的数据库用不同的驱动连接(接口不同) QDB2->DB2 QOCI->orcle QODBC->SQLServer等 QSqlDataBase类 ...
- rabbitmq, windows/linux, c/c++/node.js/golang/dotnet
官网:http://www.rabbitmq.com/ zeromq 相当于 message backbone,而rabbitmq相当于message broker.有的应用系统中,二者并存. (1) ...
- SSL/TLS算法流程解析
SSL/TLS 早已不是陌生的词汇,然而其原理及细则却不是太容易记住.本文将试图通过一些简单图示呈现其流程原理,希望读者有所收获. 一.相关版本 Version Source Description ...