ios - 无法通过 recordName UUID 查询单个 CloudKit 记录
问题描述
我有一个CloudKit
应用程序,其中记录本地存储在CoreData
. 创建CoreData
记录时,UUID
会生成 a 并将其填充到系统 recordName 字段中。该应用程序创建并保存记录,CoreData
然后将记录上传到CloudKit
. 这工作正常。
但是,我现在正在编码以修改记录,并且无法通过 recordName UUID 获取记录。我没有成功设置谓词来仅搜索该记录。我可以检索所有记录,也可以从我在记录类型TRUEPREDICATE
中创建的字段中检索单个记录。我创建了一个名为 myRecordName 的字段,其中存储了与recordNameCloudKit
相同的 UUID 。CloudKit
使用 myRecordName 的查询可以正常工作。
我在下面展示了谓词的三种方法。如果 p1 和 p2 都没有被注释掉,则应用程序在运行时崩溃。我想我在这里遗漏了一些非常简单的东西。任何指导将不胜感激。Xcode 10.2.1,iOS 12.2,在真机上测试。
如果 p1 或 p2 或两者都没有被注释掉,控制台会显示:
*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[CKReference rangeOfString:]: unrecognized selector sent to instance 0x280878520”
func queryDatabase() {
let recordZone = CKRecordZone(zoneName: "PrimaryZone")
let recName = "0E763775-5AD3-4A50-BFB8-AC310180E8A2"
let recID = CKRecord.ID(recordName: recName, zoneID: recordZone.zoneID)
let searchRecord = CKRecord(recordType: "Patient", recordID: recID)
let p1 = NSPredicate(format: "%K == %@", CKRecord.Reference(recordID: recID, action: CKRecord_Reference_Action.none))
let p2 = NSPredicate(format: "%K == %@", CKRecord.Reference(record: searchRecord, action: CKRecord_Reference_Action.none))
//let predicate = NSPredicate(format: "TRUEPREDICATE")
let p3 = NSPredicate(format: "myRecordName = %@", recName)
let query = CKQuery(recordType: "Patient", predicate: p3)
let sortDescriptor = NSSortDescriptor(key: "lastNameText", ascending: true)
query.sortDescriptors = [sortDescriptor]
privateDatabase.perform(query, inZoneWith: recordZone.zoneID) { (results, error) in
if error != nil {
print("error querying database\(String(describing: error?.localizedDescription))")
} else {
DVC.ckRecords = results!
//print(results!)
print(DVC.ckRecords.first!)
}//if error else
}//perform query block
}//queryDatabase
解决方案
我从未使用过 CloudKit,所以也许我错了,但是……</p>
两个问题代码行p1=
和p2=
尝试NSPredicate
使用格式字符串创建一个。每个格式字符串都包含两个 var arg 替换,也就是占位符:%K
和%@
. 因此,要使其正常工作,该格式字符串参数必须后跟另外两个参数:第一个是键路径,应该是字符串 (%K),第二个是其值的对象 (%@)。出于您的目的,关键路径可能只是一个属性名称。
但是您只提供了另外一个参数,一个CKRecord.Reference
对象,系统会尝试为第一个(属性名称,字符串)参数解析该对象。您得到的错误是系统尝试解析对象时发生的典型情况,例如CKRecord.Reference
当它期待一个字符串时。Swift 可能是相当安全的类型,但老式的 NSPredicate var args 函数不是:)
要解决这个问题(并继续下一个问题),您应该提供关键路径(参数名称)参数,如下所示:
let p1 = NSPredicate(format: "%K == %@", "recordID", CKRecord.Reference(recordID: recID, action: CKRecord_Reference_Action.none))
let p2 = NSPredicate(format: "%K == %@", "recordID", CKRecord.Reference(record: searchRecord, action: CKRecord_Reference_Action.none))
由于我不完全了解您在做什么,您可能需要稍微调整这两行。但关键是,给定您的格式字符串,您需要三个参数NSPredicate(format:)
,而中间的参数需要是一个表示键路径或属性名称的字符串。
推荐阅读
- java - 将 Flutter 集成到现有的 SWT Java 项目中
- r - R中逻辑回归模型的限制三次样条图
- php - Laravel Route 的 Method 错误,在 form 中更改方法
- azure-storage - 'Microsoft.Authorization/roleAssignments' 范围以引用来自不同资源组的存储帐户
- python - 为游戏中的功能插入计数器。(在整个运行过程中调用了多少次函数)
- java - 使用已经发布的无效应用程序更新我从 envato 市场购买的新应用程序
- c# - 查询的结果从实体框架查询返回相同的 COLUMN_NAME 值,这没有意义
- javascript - Atom 的反应包没有安装
- pandas - 如何进行滑动窗口转换?
- mysql - 存储过程的创建未执行