CloudKit - 如何共享多条记录并检索共享记录?

The*_*ash 1 ios icloud swift cloudkit

我在WWDC 2016上观看了CloudKit的新功能,了解如何使用CKShare与其他用户共享记录

单记录共享:

我能够共享和检索单个记录

即如果xyz@gmail.com创建并共享一条记录到abc@gmail.com

多条记录共享:

假设有10条记录,xyz @ gmail.com想要分享到 abc@gmail.com.我面临的问题,当用户xyz@gmail.com股份多个记录用户abc@gmail.com

到目前为止我尝试了什么:

首先,我创建了3个音符记录:

注1

注2(将父设为Note1)

注3(将父设为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)
Run Code Online (Sandbox Code Playgroud)

并使用以下代码检索共享注释:

代码 - 从共享注释中读取数据

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)
}
Run Code Online (Sandbox Code Playgroud)

上面的方法只给出父笔记数据(仅限root/parent)

查询:

1)如何获取其他儿童笔记?(我用术语儿童了解目的)

2)每次是否需要检查是否有新的共享记录

因为我没有找到任何好的教程和官方Apple文档的来源.你能建议我分享和检索多条记录的方法吗?

提前致谢..!

小智 8

我相信Thunk的答案是不正确的,因为您不必使用对给定记录的父引用来获取任何记录.首先,你会在哪里搜索?CKShare根记录的子记录不会出现在您的共享数据库中,并且您无权访问其他用户的专用区域.幸运的是,CloudKit将向您推送CKShare根记录所引用的所有子记录.以下方法也将解决第二个问题,您将自动收到任何和所有未来更改的通知!

关键是简单地CKDatabaseSubscription在CloudKit容器中添加一个共享数据库.我们假设您是客户.无论何时其他用户与您共享记录,CKShare记录和共享引用的基础根记录都位于该用户私有数据库的自定义区域中.当您接受共享(触发应用程序委托方法userDidAcceptCloudKitShareWith)时,您现在可以看到相同的 CKShare和基础记录,除了它们在共享数据库中都可见.如果您已订阅共享数据库,则订阅将启动并在您接受共享后立即通知您.现在,您可以使用获取共享数据库中的所有更改CKFetchDatabaseChangesOperation.在recordZoneWithIDChangedBlock,将CKRecordZoneID给出共享用户的自定义区域.您可以使用它来触发CKFetchRecordZoneChangesOperation(确保在共享数据库中执行此操作!),它返回CKShare,基础根记录以及对底层引用记录具有父引用的所有记录.

因此,通过简单的数据库订阅,您可以自动触发并下载所有共享,根记录和子项!