文章目录
  1. 1. 前言
  2. 2. 介绍
  3. 3. 使用
    1. 3.1. 增加
    2. 3.2. 查询
    3. 3.3. 删除
    4. 3.4. 修改
    5. 3.5. 订阅
  4. 4. 容器数据
  5. 5. 小知识
  6. 6. FAQ
  7. 7. 参考资料
    1. 7.1. 官方
    2. 7.2. 网络
  8. 8. 文档信息

前言


CloudKit 属于 BaaS(Backend as a Service)一种形式,能够提供基本的增删改查功能,同时提供通知订阅服务。

介绍


CKRecord 记录的类型

使用


field types
支持类型

增加


1
2
3
4
5
CKRecord * recod ...
...
[[CKContainer defaultContainer].publicCloudDatabase saveRecord:record completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {

}];

查询


CONTAINS 列表
has a value type of STRING and cannot be queried using filter type LIST_CONTAINS”>

1
2
3
4
5
NSPredicate predicate = nil;
predicate = [NSPredicate predicateWithFormat:@"ANY favoriteColors = 'red'"];
predicate = [NSPredicate predicateWithFormat:@"favoriteColors CONTAINS 'red'"];
predicate = [NSPredicate predicateWithFormat:@"'red' IN favoriteColors"];
predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS %@", @"favoriteColors", @"red"]; //%k 表示字段(存储数组的),%@ 表示包含在%k字段中的值

1
- (void)fetchRecordWithID:(CKRecordID *)recordID completionHandler:(void (^)(CKRecord * _Nullable record, NSError * _Nullable error))completionHandler;

删除


1
- (void)deleteRecordWithID:(CKRecordID *)recordID completionHandler:(void (^)(CKRecordID * _Nullable recordID, NSError * _Nullable error))completionHandler;

修改


所谓修改即:先查询,后保存。

订阅


订阅与通知相差不多,当数据发生变化时(增加、删除、更新),会收到通知。订阅的类型也是相同的,有增加、删除、更新、只收到一次订阅通知(发送后自动删除)。
通知:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
aps = {
alert = {
"loc-key" = "\U4f60\U6709\U65b0\U7684\U5b9d\U8d1d\U7559\U8a00";
};
};
ck = {
ce = 2;
cid = "iCloud.cn.xiaoneitao.app";
ckuserid = "_32e264944c0f480c52e68ceba7653371";
nid = "696d3fd0-c137-4744-8f95-49c5e8061b3a";
qry = {
dbs = 2;
fo = 1;
rid = "A47CC7B2-7FEB-4007-B5ED-373A496E5FDA";
sid = "0CB7B47E-404F-44C4-A3C3-8895B8A0FC73";
zid = "_defaultZone";
zoid = "_defaultOwner";
};
};
}
1
2
Printing description of cloudKitNotification:
<CKQueryNotification: 0x17010e460; notificationType=1, notificationID=<CKNotificationID: 0x17001a9c0; UUID=696d3fd0-c137-4744-8f95-49c5e8061b3a>, containerIdentifier=iCloud.cn.xiaoneitao.app, subscriptionID=0CB7B47E-404F-44C4-A3C3-8895B8A0FC73, alertLocalizationKey="你有新的宝贝留言", queryNotificationReason=1, recordFields=(null), recordID=<CKRecordID: 0x170038940; A47CC7B2-7FEB-4007-B5ED-373A496E5FDA:(_defaultZone:__defaultOwner__)>, database=Public>
1
2
3
4
(lldb) po response
<UNNotificationResponse: 0x174023dc0; actionIdentifier: com.apple.UNNotificationDefaultActionIdentifier, notification: <UNNotification: 0x170030c80; date: 2018-08-03 08:41:53 +0000, request: <UNNotificationRequest: 0x170023080; identifier: C9AE995A-3AA0-4749-9DE6-F19031B41509, content: <UNNotificationContent: 0x1740f8800; title: (null), subtitle: (null), body: 您的宝贝有新留言,记得来瞅瞅哈!, categoryIdentifier: , launchImageName: , peopleIdentifiers: (
), threadIdentifier: , attachments: (
), badge: (null), sound: (null), hasDefaultAction: YES, shouldAddToNotificationsList: YES, shouldAlwaysAlertWhileAppIsForeground: NO, shouldLockDevice: NO, shouldPauseMedia: NO, isSnoozeable: NO, fromSnooze: NO, darwinNotificationName: (null), darwinSnoozedNotificationName: (null), trigger: <UNPushNotificationTrigger: 0x170003210; contentAvailable: NO, mutableContent: NO>>>>

容器数据


默认容器

1
CKContainer * defaultContainer = [CKContainer defaultContainer];

自定义容器

1
CKContainer * customContainer = [CKContainer containerWithIdentifier:@"iCloud.com.devhitao.ios"];

小知识


关于 recordID.recordNamecreatorUserRecordID.recordName 的区别:

对于 Users 表中的字段值来说,若当前用户获取自己的记录:

1
2
3
4
(lldb) po userRecord.recordID.recordName
_32e264944c0f480c52e68csdsd7653371 //用户唯一标识 或 这条记录的唯一标识
(lldb) po userRecord.creatorUserRecordID.recordName
__defaultOwner__

对于当前用户, 获取 Users 表中其他用户的记录返回值 creatorUserRecordID.recordNamerecordID.recordName 相同。

对于当前用户,获取非自己创建的 Record(其他Record, 不包括 Users):

1
2
3
4
(lldb) po userRecord.recordID.recordName
_32e264944c0f480c52e68csdsd7653371 //这条记录的唯一标识
(lldb) po userRecord.creatorUserRecordID.recordName
_42323e264944c0f480c52e68csdsdsd76 //这条记录创建人的唯一标识

对于其他 Record,若当前创建人请求自己创建的 Record,userRecord.creatorUserRecordID.recordName 返回__defaultOwner__userRecord.recordID.recordName为记录的唯一 id。

注:
CloudKit Dashboard 分为开发环境和生产环境,在 deployed 之前,可以在开发环境中删除 record types 和 Fields,发布之后不能够再修改已发布的 Record 和 字段 类型。

常量

1
2
3
4
CKCurrentUserDefaultName
__defaultOwner__
CKOwnerDefaultName
__defaultOwner__

FAQ


Q: 在 Xcode 中访问 Cloudkit 生产环境 中的数据?
A: 在 Example.entitlements 环境中,添加 com.apple.developer.icloud-container-environment 并设置为 Production 即可,已验证可行。(注:需要重新编译工程,清除缓存)

1
2
<key>com.apple.developer.icloud-container-environment</key>
<string>Production</string>

参考来源:Use production CloudKit during development?


Q: 当使用 initWithRecordType:predicate: 方法检索 Users 记录集合时会遇到 "Permission Failure" (10/2007); server message = "Can't query system types";,大概意思是不允许查询系统类型字段,同时苹果官方给出的信息是:

You cannot query for user records and executing a query where the record type is set to CKRecordTypeUserRecord results in an error. You must fetch user records directly using their ID.

您不能查询用户记录集,并且当执行查询 Record Type 为 CKRecordTypeUserRecord 结果集时会出现一个错误。你必须使用其ID直接获取用户记录。


Q: "Invalid Arguments" (12/2006); server message = "attempt to add owning ref to user rec"; 将其改为 CKReference * userRefer = [[CKReference alloc] initWithRecord:aliasRecord action:CKReferenceActionNone];

Error when saving user record: “attempt to add owning ref to user rec”


Q: 每条记录大小问题

To ensure the speed of fetching and saving records, the data stored by a record must not exceed 1 MB. Assets do not count against this limit but all other data types do.

为了确保记录的抓取和保存速度,存储在记录中的数据一定不要超过 1 MB,Assets 类型不会被计算在内且不受此限制,但是上面其他类型都需要准守。


Q: 当出现Field 'recordName' is not marked queryable时,意思是提醒我们索引不存在,需要在控制板中将此记录字段添加到可查询索引。

参考资料


因为在学习过程中遇到的问题比较多,所以参考的资料就多,大致分为官方资料和网络资料两种。

官方


网络


文档信息


  • 版权声明:自由转载-保持署名-非商用-非衍生 ( CC BY-NC-ND 4.0 )
文章目录
  1. 1. 前言
  2. 2. 介绍
  3. 3. 使用
    1. 3.1. 增加
    2. 3.2. 查询
    3. 3.3. 删除
    4. 3.4. 修改
    5. 3.5. 订阅
  4. 4. 容器数据
  5. 5. 小知识
  6. 6. FAQ
  7. 7. 参考资料
    1. 7.1. 官方
    2. 7.2. 网络
  8. 8. 文档信息