云套件共享

5
我不理解一些CloudKit分享的概念,WWDC 2016“CloudKit的新功能”视频似乎没有解释允许用户共享和访问共享记录所需的所有内容。
我已成功创建了一个应用程序,允许用户在其私有数据库中创建和编辑记录。我还能够创建共享记录并使用提供的共享UIController进行共享。接收方用户可以成功接收和接受分享,但我无法找到如何查询和显示此共享记录的方法。
该应用程序在用户的私有数据库中创建一个“MainZone”,然后在此“MainZone”中创建并保存CKRecord。然后我创建并保存一个CKShare记录,并将其用于显示UICloudSharingController。
我该如何查询共享数据库以访问此记录?我尝试使用与privateDatabase中使用的相同查询,但出现以下错误:
"ShareDB can't be used to access local zone"

编辑

我发现问题所在 - 我需要在AppDelegate中处理已接受的记录。现在它们出现在CloudKit仪表板中,但我仍然无法查询它们。看起来我可能需要获取共享数据库“MainZone”才能查询它们。

2个回答

4
兄弟,我知道了:首先你需要获取该共享记录的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")
            }
        }
    }
}

2
我不建议这种方法,如果有数百万用户共享东西会发生什么?将会有数百万个记录区域,因此这个查询可能非常大。我认为正确的方法似乎是存储与您的用户共享的本地引用,并使用这些引用来查询更改。我认为这个想法也是为了最小化查询,而是注册更改,然后处理更改 - 但我担心在某些情况下这也可能导致太多的推送流量。 - Duncan Groenewald
嗯 - 事实上,您可能是正确的,因为用户只能看到与他们共享的记录中的区域! - Duncan Groenewald

1

我不是很清楚您想获取那些信息的时间。我和您一样有同样的问题,但我只能通过点击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)
}

正如我之前所说,我现在正在尝试获取ShareDB而不访问URL。一旦我已经接受了共享,我不想依赖于链接。希望这可以帮助你!


谢谢,这很有道理,但我该如何从数据库中查询所有共享记录?或者App是否需要保留自己的这些共享记录副本(在本地或privateDatabase中)?我不想在本地存储数据,只想查询共享记录,但似乎除了查询每个共享区域之外没有其他方法。 - Duncan Groenewald
很遗憾,我和你一样,正在尝试解决这个问题。共享内容不会留在你的privateDB中,而是留在sharedDB中。我尝试的做法是像普通的CKRecord一样查询,毕竟CKShare是对CKRecord的引用!但是一旦我使用ZoneID执行查询,我得到了与你相同的消息:“ShareDB不能用于访问本地区域”。 - Pedro de Sá
2
我检查了记录的zoneID和在zoneID中查询,这个工作很好。因此,我保留了私有数据库zoneID并将其与记录的zoneID进行比较,如果它们不匹配,则知道它必须是一个sharedDatabase查询,然后在查询中需要zoneID。现在,我将在privateDatabase中存储所有共享zoneID的副本,以便轻松知道要在sharedDatabase中查询哪些区域。 - Duncan Groenewald
1
我现在明白了,这个消息“ShareDB无法用于访问本地区域”之所以出现,是因为我使用的是privateDB的ZoneID,而不是sharedDB的! - Pedro de Sá

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接