我上次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
时,我遇到了问题到目前为止我尝试了什么:
首先我创建了3个音符记录:
注1
Note2(将parent设置为Note1)
Note3(将parent设置为Note1)
我与下面的代码共享Note1(父记录):
代码 - 分享记录
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)
并使用以下代码检索共享注释:
代码 - 从共享注释中读取数据
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)
}
上述方法仅提供父记录数据(仅限root / parent)
查询:
1)如何获取其他儿童音符记录? (我用术语儿童来理解目的)
2)每次是否需要检查是否有新的共享记录
因为我没有找到任何好的教程和官方Apple文档的来源。你能建议我分享和检索多条记录的方法吗?
提前致谢..!
答案 0 :(得分:7)
我认为Thunk的答案是不正确的,因为您不必使用对给定记录的父引用来获取任何记录。首先,你会在哪里搜索? CKShare根记录的子记录不会出现在您的共享数据库中,并且您无权访问其他用户的专用区域。幸运的是,CloudKit将向您推送CKShare根记录所引用的所有子记录。以下方法也将解决第二个问题,您将自动收到任何和所有未来更改的通知!
关键是简单地将CKDatabaseSubscription
添加到CloudKit容器中的共享数据库。我们假设您是客户。无论何时其他用户与您共享记录,CKShare记录和共享引用的基础根记录都位于该用户私有数据库的自定义区域中。当您接受共享(触发应用程序委托方法userDidAcceptCloudKitShareWith
)时,您现在可以看到相同的 CKShare和基础记录,除了它们在共享<中都可见/ em>数据库。如果您已订阅共享数据库,则订阅将启动并在您接受共享后立即通知您。现在,您可以使用CKFetchDatabaseChangesOperation
获取共享数据库中的所有更改。在recordZoneWithIDChangedBlock
中,将提供共享用户自定义区域的CKRecordZoneID
。您可以使用它来触发CKFetchRecordZoneChangesOperation
(确保在共享数据库中执行此操作!),它返回CKShare,基础根记录,以及所有对底层引用具有父引用的记录记录。
因此,通过简单的数据库订阅,您可以自动触发并下载所有共享,根记录和子项!
答案 1 :(得分:1)
关于问题1,要查找引用父项的记录,您需要创建一个检查rootRecordID引用字段的查询。 Apple的这个页面有一节讨论检索选项和代码示例。
关于问题2,您可以不断轮询服务器以获取更新的记录,但Apple不鼓励在其中一个WWDC视频中,因为它会产生大量网络流量(因此会烧毁您的每月配额)。我建议在CKshare上添加订阅通知。这样,当您需要获取记录时,您将收到通知。