CloudKit - 如何共享多条记录和检索共享记录?
CloudKit - How to share multiple records and retrieve shared records?
我看了最后 WWDC 2016 What's New with CloudKit 以了解如何使用 CKShare
与其他用户共享记录
单条记录分享:
我能够共享和检索单个记录
即,如果 xyz@gmail.com 已创建一条记录并将其共享到 abc@gmail.com
多条记录共享:
假设有 10 条记录,xyz@gmail.com 想分享给 abc@gmail.com .当用户 xyz@gmail.com 向用户 abc@gmail.com [=14= 共享多条记录时,我遇到了这个问题]
目前我尝试过的:
首先我创建了3条笔记记录:
备注1
注2(设置parent为注1)
注3(设置parent为注1)
我用以下代码分享了 Note1(Parent 记录):
CODE - 分享记录
let controller = UICloudSharingController { controller,
preparationCompletionHandler in
let share = CKShare(rootRecord: self.parentRecord!)
share[CKShareTitleKey] = "note" as CKRecordValue
share.publicPermission = .readOnly
let operation = CKModifyRecordsOperation(
recordsToSave: [self.parentRecord!, share],
recordIDsToDelete: nil)
operation.perRecordCompletionBlock = { (record, error) in
if let error = error {
print("CloudKit error: \(error.localizedDescription)")
}
}
operation.modifyRecordsCompletionBlock = { records, recordIDs, error in
if error != nil {
print(error?.localizedDescription ?? "Error")
} else{
print("Success")
preparationCompletionHandler(share,CKContainer.default(), error)
}
}
CKContainer.default().privateCloudDatabase.add(operation)
}
controller.availablePermissions = [.allowPrivate, .allowReadOnly]
controller.delegate = self
present(controller, animated: true)
并使用以下代码检索 shared-note:
CODE - 从 shared-note
读取数据
func application(_ application: UIApplication, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShareMetadata) {
let acceptSharesOperation = CKAcceptSharesOperation(
shareMetadatas: [cloudKitShareMetadata])
acceptSharesOperation.perShareCompletionBlock = {
metadata, share, error in
if error != nil {
print(error?.localizedDescription)
} else {
let operation = CKFetchRecordsOperation(
recordIDs: [cloudKitShareMetadata.rootRecordID])
operation.perRecordCompletionBlock = { record, _, error in
if error != nil {
print(error?.localizedDescription)
}
if let shareRecord = record {
DispatchQueue.main.async() {
// Shared record successfully fetched. Update user
// interface here to present to user.
print("\(shareRecord["id"]!)") // id of note
print("\(shareRecord["text"])") // text of note
print("Shared record successfully fetched")
}
}
}
operation.fetchRecordsCompletionBlock = { (recordsWithRecordIDs,error) in
if error != nil {
print(error?.localizedDescription)
}else {
if let recordsWithRecordIDs = recordsWithRecordIDs {
print("Count \(recordsWithRecordIDs.count)")
}
}
}
CKContainer.default().sharedCloudDatabase.add(operation)
}
}
CKContainer(identifier: cloudKitShareMetadata.containerIdentifier)
.add(acceptSharesOperation)
}
以上方法仅提供 parent 注释数据(仅 root/parent )
查询:
1) 如何获取其他children条笔记记录? (为了便于理解,我使用了术语 children)
2)是否需要每次检查是否有新的共享记录
因为我还没有找到任何好的教程和苹果官方文档的来源。你会建议我共享和检索多条记录的方法吗?
提前致谢..!
关于问题 1,要查找引用父项的记录,您需要创建一个查询来检查 rootRecordID 的引用字段。 Apple 的这个页面有一个部分讨论了带有代码示例的检索选项。
关于问题 2,您可以不断轮询服务器以获取更新的记录,但 Apple 在其中一个 WWDC 视频中不鼓励这样做,因为它会产生大量网络流量(因此会耗尽您的每月配额)。我建议在 CKshare 上加一个订阅通知。这样,当您需要获取记录时,您会收到通知。
我认为 Thunk 的回答是不正确的,因为您不必获取任何具有对给定记录的父引用的记录。首先,你会在哪里搜索? CKShare 根记录的子记录不会出现在您的共享数据库中,您无权访问其他用户的私有区域。幸运的是,CloudKit 会将 CKShare 的根记录引用的所有子记录推送给您。以下方法也将解决第二个问题,您将自动收到任何和所有未来更改的通知!
关键是简单的在CloudKit容器中添加一个CKDatabaseSubscription
到共享数据库。假设您是客户。每当另一个用户与您共享记录时,共享引用的 CKShare 记录和基础根记录都位于该用户私有数据库的自定义区域中。当您接受共享(触发应用程序委托方法 userDidAcceptCloudKitShareWith
)时,same CKShare 和基础记录现在对您可见,除了它们都在您的 共享 数据库。如果您订阅了共享数据库,订阅将在您接受共享后立即启动并通知您。现在您可以使用 CKFetchDatabaseChangesOperation
获取共享数据库中的所有更改。在recordZoneWithIDChangedBlock
中,会给出分享用户自定义区域的CKRecordZoneID
。您使用它来触发一个 CKFetchRecordZoneChangesOperation
(一定要在共享数据库中执行此操作!),其中 returns CKShare、底层根记录和 所有具有对基础引用记录的父引用。
因此,通过简单的数据库订阅,您可以自动触发并下载所有共享、根记录和子项!
我看了最后 WWDC 2016 What's New with CloudKit 以了解如何使用 CKShare
与其他用户共享记录单条记录分享:
我能够共享和检索单个记录
即,如果 xyz@gmail.com 已创建一条记录并将其共享到 abc@gmail.com
多条记录共享:
假设有 10 条记录,xyz@gmail.com 想分享给 abc@gmail.com .当用户 xyz@gmail.com 向用户 abc@gmail.com [=14= 共享多条记录时,我遇到了这个问题]
目前我尝试过的:
首先我创建了3条笔记记录:
备注1
注2(设置parent为注1)
注3(设置parent为注1)
我用以下代码分享了 Note1(Parent 记录):
CODE - 分享记录
let controller = UICloudSharingController { controller,
preparationCompletionHandler in
let share = CKShare(rootRecord: self.parentRecord!)
share[CKShareTitleKey] = "note" as CKRecordValue
share.publicPermission = .readOnly
let operation = CKModifyRecordsOperation(
recordsToSave: [self.parentRecord!, share],
recordIDsToDelete: nil)
operation.perRecordCompletionBlock = { (record, error) in
if let error = error {
print("CloudKit error: \(error.localizedDescription)")
}
}
operation.modifyRecordsCompletionBlock = { records, recordIDs, error in
if error != nil {
print(error?.localizedDescription ?? "Error")
} else{
print("Success")
preparationCompletionHandler(share,CKContainer.default(), error)
}
}
CKContainer.default().privateCloudDatabase.add(operation)
}
controller.availablePermissions = [.allowPrivate, .allowReadOnly]
controller.delegate = self
present(controller, animated: true)
并使用以下代码检索 shared-note:
CODE - 从 shared-note
读取数据func application(_ application: UIApplication, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShareMetadata) {
let acceptSharesOperation = CKAcceptSharesOperation(
shareMetadatas: [cloudKitShareMetadata])
acceptSharesOperation.perShareCompletionBlock = {
metadata, share, error in
if error != nil {
print(error?.localizedDescription)
} else {
let operation = CKFetchRecordsOperation(
recordIDs: [cloudKitShareMetadata.rootRecordID])
operation.perRecordCompletionBlock = { record, _, error in
if error != nil {
print(error?.localizedDescription)
}
if let shareRecord = record {
DispatchQueue.main.async() {
// Shared record successfully fetched. Update user
// interface here to present to user.
print("\(shareRecord["id"]!)") // id of note
print("\(shareRecord["text"])") // text of note
print("Shared record successfully fetched")
}
}
}
operation.fetchRecordsCompletionBlock = { (recordsWithRecordIDs,error) in
if error != nil {
print(error?.localizedDescription)
}else {
if let recordsWithRecordIDs = recordsWithRecordIDs {
print("Count \(recordsWithRecordIDs.count)")
}
}
}
CKContainer.default().sharedCloudDatabase.add(operation)
}
}
CKContainer(identifier: cloudKitShareMetadata.containerIdentifier)
.add(acceptSharesOperation)
}
以上方法仅提供 parent 注释数据(仅 root/parent )
查询:
1) 如何获取其他children条笔记记录? (为了便于理解,我使用了术语 children)
2)是否需要每次检查是否有新的共享记录
因为我还没有找到任何好的教程和苹果官方文档的来源。你会建议我共享和检索多条记录的方法吗?
提前致谢..!
关于问题 1,要查找引用父项的记录,您需要创建一个查询来检查 rootRecordID 的引用字段。 Apple 的这个页面有一个部分讨论了带有代码示例的检索选项。
关于问题 2,您可以不断轮询服务器以获取更新的记录,但 Apple 在其中一个 WWDC 视频中不鼓励这样做,因为它会产生大量网络流量(因此会耗尽您的每月配额)。我建议在 CKshare 上加一个订阅通知。这样,当您需要获取记录时,您会收到通知。
我认为 Thunk 的回答是不正确的,因为您不必获取任何具有对给定记录的父引用的记录。首先,你会在哪里搜索? CKShare 根记录的子记录不会出现在您的共享数据库中,您无权访问其他用户的私有区域。幸运的是,CloudKit 会将 CKShare 的根记录引用的所有子记录推送给您。以下方法也将解决第二个问题,您将自动收到任何和所有未来更改的通知!
关键是简单的在CloudKit容器中添加一个CKDatabaseSubscription
到共享数据库。假设您是客户。每当另一个用户与您共享记录时,共享引用的 CKShare 记录和基础根记录都位于该用户私有数据库的自定义区域中。当您接受共享(触发应用程序委托方法 userDidAcceptCloudKitShareWith
)时,same CKShare 和基础记录现在对您可见,除了它们都在您的 共享 数据库。如果您订阅了共享数据库,订阅将在您接受共享后立即启动并通知您。现在您可以使用 CKFetchDatabaseChangesOperation
获取共享数据库中的所有更改。在recordZoneWithIDChangedBlock
中,会给出分享用户自定义区域的CKRecordZoneID
。您使用它来触发一个 CKFetchRecordZoneChangesOperation
(一定要在共享数据库中执行此操作!),其中 returns CKShare、底层根记录和 所有具有对基础引用记录的父引用。
因此,通过简单的数据库订阅,您可以自动触发并下载所有共享、根记录和子项!