CloudKit 分享
CloudKit Sharing
我无法理解一些 CloudKit 共享概念,WWDC 2016 "What's new in CloudKit" 视频似乎没有解释允许用户共享和访问共享记录所需的所有内容。
我已经成功创建了一个允许用户在他们的私人数据库中创建和编辑记录的应用程序。
我还能够创建共享记录并使用提供的共享 UIController 共享它。这可以被参与用户成功接收并接受,但我无法弄清楚如何查询和显示此共享记录。
该应用程序在用户私有数据库中创建一个 "MainZone",然后在该 "MainZone" 中创建一个 CKRecord。然后我创建并保存一个 CKShare 记录并使用它来显示 UICloudSharingController。
如何查询 sharedDatabase 以访问此记录?我尝试使用与 privateDatabase 中使用的查询相同的查询,但出现以下错误:
"ShareDB can't be used to access local zone"
编辑
我发现了问题 - 我需要在 AppDelegate 中处理接受的记录。现在它们出现在 CloudKit 仪表板中,但我仍然无法查询它们。看来我可能需要获取 sharedDatabase "MainZone" 才能查询它们。
我不太了解何时您想获得这些信息。我和你有同样的问题,但我只能通过单击 URL... 来获取共享数据...为此,你需要两个函数。 AppDelegate 中的第一个:
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 viewController: ViewController = self.window?.rootViewController as! ViewController
viewController.fetchShare(cloudKitShareMetadata)
}
}
CKContainer(identifier: cloudKitShareMetadata.containerIdentifier).add(acceptSharesOperation)
}
在 ViewConroller 中,您具有将获取此元数据的函数:
func fetchShare(_ metadata: CKShareMetadata) {
let operation = CKFetchRecordsOperation(recordIDs: [metadata.rootRecordID])
operation.perRecordCompletionBlock = { record, _, error in
if error != nil {
print(error?.localizedDescription)
}
if record != nil {
DispatchQueue.main.async() {
self.currentRecord = record
//now you have your Shared Record
}
}
}
operation.fetchRecordsCompletionBlock = { _, error in
if error != nil {
print(error?.localizedDescription)
}
}
CKContainer.default().sharedCloudDatabase.add(operation)
}
正如我之前所说,我现在正在尝试在不访问 URL 的情况下获取 ShareDB。一旦我已经接受了共享,我不想依赖 link。希望对你有帮助!
伙计,我明白了:首先你需要获取该共享记录的 CKRecordZone。您可以通过执行以下操作来完成:
let sharedData = CKContainer.default().sharedCloudDatabase
sharedData.fetchAllRecordZones { (recordZone, error) in
if error != nil {
print(error?.localizedDescription)
}
if let recordZones = recordZone {
// Here you'll have an array of CKRecordZone that is in your SharedDB!
}
}
现在,有了这个数组,您所要做的就是正常获取:
func showData(id: CKRecordZoneID) {
ctUsers = [CKRecord]()
let sharedData = CKContainer.default().sharedCloudDatabase
let predicate = NSPredicate(format: "TRUEPREDICATE")
let query = CKQuery(recordType: "Elder", predicate: predicate)
sharedData.perform(query, inZoneWith: id) { results, error in
if let error = error {
DispatchQueue.main.async {
print("Cloud Query Error - Fetch Establishments: \(error)")
}
return
}
if let users = results {
print(results)
self.ctUsers = users
print("\nHow many shares in cloud: \(self.ctUsers.count)\n")
if self.ctUsers.count != 0 {
// Here you'll your Shared CKRecords!
}
else {
print("No shares in SharedDB\n")
}
}
}
}
我无法理解一些 CloudKit 共享概念,WWDC 2016 "What's new in CloudKit" 视频似乎没有解释允许用户共享和访问共享记录所需的所有内容。
我已经成功创建了一个允许用户在他们的私人数据库中创建和编辑记录的应用程序。 我还能够创建共享记录并使用提供的共享 UIController 共享它。这可以被参与用户成功接收并接受,但我无法弄清楚如何查询和显示此共享记录。
该应用程序在用户私有数据库中创建一个 "MainZone",然后在该 "MainZone" 中创建一个 CKRecord。然后我创建并保存一个 CKShare 记录并使用它来显示 UICloudSharingController。
如何查询 sharedDatabase 以访问此记录?我尝试使用与 privateDatabase 中使用的查询相同的查询,但出现以下错误:
"ShareDB can't be used to access local zone"
编辑
我发现了问题 - 我需要在 AppDelegate 中处理接受的记录。现在它们出现在 CloudKit 仪表板中,但我仍然无法查询它们。看来我可能需要获取 sharedDatabase "MainZone" 才能查询它们。
我不太了解何时您想获得这些信息。我和你有同样的问题,但我只能通过单击 URL... 来获取共享数据...为此,你需要两个函数。 AppDelegate 中的第一个:
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 viewController: ViewController = self.window?.rootViewController as! ViewController
viewController.fetchShare(cloudKitShareMetadata)
}
}
CKContainer(identifier: cloudKitShareMetadata.containerIdentifier).add(acceptSharesOperation)
}
在 ViewConroller 中,您具有将获取此元数据的函数:
func fetchShare(_ metadata: CKShareMetadata) {
let operation = CKFetchRecordsOperation(recordIDs: [metadata.rootRecordID])
operation.perRecordCompletionBlock = { record, _, error in
if error != nil {
print(error?.localizedDescription)
}
if record != nil {
DispatchQueue.main.async() {
self.currentRecord = record
//now you have your Shared Record
}
}
}
operation.fetchRecordsCompletionBlock = { _, error in
if error != nil {
print(error?.localizedDescription)
}
}
CKContainer.default().sharedCloudDatabase.add(operation)
}
正如我之前所说,我现在正在尝试在不访问 URL 的情况下获取 ShareDB。一旦我已经接受了共享,我不想依赖 link。希望对你有帮助!
伙计,我明白了:首先你需要获取该共享记录的 CKRecordZone。您可以通过执行以下操作来完成:
let sharedData = CKContainer.default().sharedCloudDatabase
sharedData.fetchAllRecordZones { (recordZone, error) in
if error != nil {
print(error?.localizedDescription)
}
if let recordZones = recordZone {
// Here you'll have an array of CKRecordZone that is in your SharedDB!
}
}
现在,有了这个数组,您所要做的就是正常获取:
func showData(id: CKRecordZoneID) {
ctUsers = [CKRecord]()
let sharedData = CKContainer.default().sharedCloudDatabase
let predicate = NSPredicate(format: "TRUEPREDICATE")
let query = CKQuery(recordType: "Elder", predicate: predicate)
sharedData.perform(query, inZoneWith: id) { results, error in
if let error = error {
DispatchQueue.main.async {
print("Cloud Query Error - Fetch Establishments: \(error)")
}
return
}
if let users = results {
print(results)
self.ctUsers = users
print("\nHow many shares in cloud: \(self.ctUsers.count)\n")
if self.ctUsers.count != 0 {
// Here you'll your Shared CKRecords!
}
else {
print("No shares in SharedDB\n")
}
}
}
}