为啥 CloudKit 不允许我将任何记录保存到默认容器的公共数据库中?
Posted
技术标签:
【中文标题】为啥 CloudKit 不允许我将任何记录保存到默认容器的公共数据库中?【英文标题】:Why is CloudKit not allowing me to save any records to my default container's public database?为什么 CloudKit 不允许我将任何记录保存到默认容器的公共数据库中? 【发布时间】:2017-09-11 05:41:16 【问题描述】:我有一个 CKRecords 数组,我第一次尝试将它们保存到默认 Container 的公共数据库中。我创建了一个 CKModifyRecordsOperation 并尝试将该操作添加到公共数据库。它不成功,但我没有收到任何错误消息。所以我尝试将每个方法单独添加到数据库中,没有任何 CKOperation ......同样不成功,也没有错误消息。可以肯定的是,我检查了我的 CloudKit 仪表板;那里什么都没有。
以下是有问题的方法。它连接到一个简单的 IBAction,用于 NSWindow 中的按钮。您可以忽略我从模型数据创建 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())")
//
//
【问题讨论】:
您是否收到任何打印声明? 您是否使用CKContainer accountStatus(completionHandler:)
方法验证了对容器的访问权限?
是的,我有:它可用。另一方面,我刚刚意识到为什么我没有收到任何错误消息。这是因为我的警卫声明很愚蠢……一个否定错误。不过,现在我已经修复了它,它给了我这个错误:There was an error: You can't save the same record twice: <CKRecordID: 0x608000034420; recordName=067A4A65-B2E5-4DEA-974D-7354849D7D59, zoneID=_defaultZone:__defaultOwner__>
。但是,当我通过 CloudKit Dashboard 检查时,数据库中没有保存任何数据。知道可能是什么问题吗?谢谢。
您是否在仪表板中查看正确的容器?
是的,我是。我也只是重置了该容器中的开发环境。我假设如果公共数据库中有任何东西,这个动作就会清空它,对吧?好吧,我尝试再次以编程方式上传数据......它仍然给我同样的错误。
【参考方案1】:
重复记录的问题是您重复使用了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")
【讨论】:
噢,伙计。这很有意义。谢谢!所以......我解决了这个问题......我现在得到的错误说我有“我的容器的 BundleId 无效”。您的 BundleID 是否应该采用特定格式?比如,反向 DNS 表示法之类的?再次感谢,伙计。如果可以的话,我会接受你的回答……但我只有 13 个代表点 :( 您可以接受答案,但可能需要等待几分钟。代表不是接受您自己问题的答案的问题。至于容器问题,您的应用程序是否设置为使用 Xcode 中的默认容器? 知道了。它被接受了。是的;它设置为使用默认容器。不应该吗? 应该没问题。我想知道这是否是一个暂时的问题。几个小时前另一个人发布了同样的问题:***.com/questions/46144170/… 嗯。有可能。我想我会在几个小时后再试一次,看看会发生什么。再次感谢您的帮助,伙计。以上是关于为啥 CloudKit 不允许我将任何记录保存到默认容器的公共数据库中?的主要内容,如果未能解决你的问题,请参考以下文章
为啥CKModifyRecordsOperation批量删除CloudKit中的记录不删除记录?