为什么 CloudKit 不允许我将任何记录保存到默认容器的 public 数据库中?

Why is CloudKit not allowing me to save any records to my default container's public database?

我有一个 CKRecords 数组,这是我第一次尝试将其保存到默认 Container 的 public 数据库中。我创建了一个 CKModifyRecordsOperation 并尝试将操作添加到 public 数据库。它不成功,但我没有收到任何错误消息。所以我尝试将每个方法单独添加到数据库中,没有任何 CKOperation ... 也不成功,也没有错误消息。可以肯定的是,我检查了我的 CloudKit 仪表板;那里什么都没有。

下面是有问题的方法。它连接到 NSWindow 中按钮的简单 IBAction。您可以忽略我从模型数据创建 CKRecords 的嵌套循环。他们似乎按预期工作。我的错误检查代码位于 CKModifyRecordsOperation 的完成块内。具体来说,modifyRecordsCompletionBlock 正在打印:"Saved 0 records into CloudKit."

    @IBAction func uploadDataToCloudKit(_ sender: NSButton) {
        // Get CloudKit container and Public Database
        let myContainer = CKContainer.default()
        let publicDB = myContainer.publicCloudDatabase

        // Create array of cloudkit records so we can save a batch
        var cloudRecords = [CKRecord]()

        let groups = PayCodes().groups

        // For each PayCode Group...
        for payCodeGroup in groups {
            // Create CKRecord and give it a type
            let payCodeGroupRecord = CKRecord(recordType: "payCodeData")

            // For each PayCode in the group...
            for payCode in payCodeGroup.payCodes {
                // Fill the new CKRecord with key/value pairs
                payCodeGroupRecord.setObject(payCodeGroup.title as NSString, forKey: "group")

                if let commercialID = payCode.id.commercial as NSString?, let residentialID = payCode.id.residential as NSString? {
                    payCodeGroupRecord.setObject(commercialID, forKey: "commercialID")
                    payCodeGroupRecord.setObject(residentialID, forKey: "residentialID")
                }

                payCodeGroupRecord.setObject(payCode.title as NSString, forKey: "title")

                if let description = payCode.description as NSString? {
                    payCodeGroupRecord.setObject(description, forKey: "description")
                }

                payCodeGroupRecord.setObject((payCode.includesTripCharge ? 1 : 0) as NSNumber, forKey: "includesTripCharge")
                payCodeGroupRecord.setObject((payCode.needsResolutionCode ? 1 : 0) as NSNumber, forKey: "needsResolutionCode")


                payCodeGroupRecord.setObject(payCode.pay.commercial as NSNumber, forKey: "commercialPay")
                payCodeGroupRecord.setObject(payCode.pay.residential as NSNumber, forKey: "residentialPay")

                // Save new CKRecord into the Array
                cloudRecords.append(payCodeGroupRecord)
            }
        }

        print("There are \(cloudRecords.count) records about to be saved...")
        // print(cloudRecords)
        // Create an operation to save the records
        let operation = CKModifyRecordsOperation(recordsToSave: cloudRecords, recordIDsToDelete: nil)

        operation.perRecordCompletionBlock = { savedRecord, error in
            guard error != nil else {
                print("There was an error: \(error!.localizedDescription)")
                return
            }

            print("Saved a record into CloudKit")
        }

        operation.modifyRecordsCompletionBlock = { savedRecords, deletedRecordIDs, error in
            guard error != nil else {
                print("There was an error: \(error!.localizedDescription)")
                return
            }

            guard let savedRecords = savedRecords else { return }
            print("Saved \(savedRecords.count) records into CloudKit")
        }

        // Run the operation
        publicDB.add(operation)
//        cloudRecords.forEach { record in
//            publicDB.save(record) { savedRecord, error in
//                guard error != nil else {
//                    print("There was an error: \(error!.localizedDescription)")
//                    return
//                }
//                
//                guard let savedRecord = savedRecord else { return }
//                print("Saved a record: \(savedRecord.allKeys())")
//            }
//        }
    }

您的重复记录问题是您对 CKRecord 实例的重用。

变化:

for payCodeGroup in groups {
    // Create CKRecord and give it a type
    let payCodeGroupRecord = CKRecord(recordType: "payCodeData")

    // For each PayCode in the group...
    for payCode in payCodeGroup.payCodes {
        // Fill the new CKRecord with key/value pairs
        payCodeGroupRecord.setObject(payCodeGroup.title as NSString, forKey: "group")

至:

for payCodeGroup in groups {
    // For each PayCode in the group...
    for payCode in payCodeGroup.payCodes {
        // Create CKRecord and give it a type
        let payCodeGroupRecord = CKRecord(recordType: "payCodeData")

        // Fill the new CKRecord with key/value pairs
        payCodeGroupRecord.setObject(payCodeGroup.title as NSString, forKey: "group")