我第一次使用CloudKit,在执行CKQueryOperation查询给定类型的所有记录时遇到困难。苹果不赞成我在网上找到的大部分东西,除了func声明之外,这些东西的文档完全是空白的,这一点也没有帮助。我想我已经完成了代码的“框架”,但我不确定.recordMatchedBlock和.queryResultsBlock中会出现什么。
我有一个func queryAllNotes(),它应该查询"Notes“类型的公共数据库中的所有记录,并返回注释标题及其关联的cloudID的元组数组,这正是添加到数据库时给它的唯一recordName。
下面是queryAllNotes()的代码:
private func queryAllNotes() -> [(title: String, cloudID: String)] {
/*
query all notes in the cloud DB into an array to populate
the tableView
*/
var resultArray: [(title: String, cloudID: String)] = []
//set the cloud database to .publicCloudDatabase
let container = CKContainer.default()
let cloudDB = container.publicCloudDatabase
let pred = NSPredicate(value: true) //true -> return all records
let query = CKQuery(recordType: "Notes", predicate: pred)
let queryOperation = CKQueryOperation(query: query)
queryOperation.database = cloudDB
queryOperation.resultsLimit = 100
queryOperation.recordMatchedBlock = { (record: CKRecord) in
let noteTitle = record["Title"] as! String
let noteCloudID = record.recordID.recordName
resultArray.append((noteTitle, noteCloudID))
}
queryOperation.queryResultBlock = { (cursor, error) in
}
return resultArray
}据我理解,对查询返回的每条记录都调用了.recordMatchedBlock,因此我认为它是完整的,但我可能大错特错。关于.queryResultBlock,我的理解是,从技术上讲,查询一次只返回一条记录,这个块基本上告诉查询为.resultLimit中的所有记录再次运行下一条记录。如何构造此查询?我很想了解每一个街区的作用。
另外,这是一个macOS应用程序;我不知道macOS和iOS的代码是否不同,但我想我应该包括这个,以防万一。
另外,我说“没有更多上下文的表达式类型是模棱两可的”是错误的,这是因为我还没有完成查询的设置。如果是因为不同的原因,也可以解释为什么会发生这种情况。
编辑
我把这个功能称为viewDidLoad()内部的功能,如下所示:
//array var for the array that is used to populate the tableView
var noteRecords: [(title: String, cloudID: String)] = []
override func viewDidLoad() {
super.viewDidLoad()
// do additional setup here
// set serachField delegate
searchField.delegate = self
// set tableView delegate and data source
tableView.delegate = self
tableView.dataSource = self
// load all NoteRecords in public cloud db into noteRecords
noteRecords = queryAllNotes()
}发布于 2022-03-18 16:06:39
使用新的async模式,从CloudKit中获取数据变得更加容易。
而不是CKQueryOperation,而是直接调用records(matching:resultsLimit:),并将结果映射到任何您喜欢的地方。
一个可能的错误被移交给调用者。
func queryAllNotes() async throws -> [(title: String, cloudID: String)] {
//set the cloud database to .publicCloudDatabase
let container = CKContainer.default()
let cloudDB = container.publicCloudDatabase
let pred = NSPredicate(value: true) //true -> return all records
let query = CKQuery(recordType: "Notes", predicate: pred)
let (notesResults, _) = try await cloudDB.records(matching: query,
resultsLimit: 100)
return notesResults
.compactMap { _, result in
guard let record = try? result.get(),
let noteTitle = record["Title"] as? String else { return nil }
return (title: noteTitle, cloudID: record.recordID.recordName)
}
}并使用它
override func viewDidLoad() {
super.viewDidLoad()
// do additional setup here
// set serachField delegate
searchField.delegate = self
// set tableView delegate and data source
tableView.delegate = self
tableView.dataSource = self
// load all NoteRecords in public cloud db into noteRecords
Task {
do {
noteRecords = try await queryAllNotes()
tableView.reloadData()
} catch {
print(error)
}
}
}有关async CloudKit API和GitHub上的苹果实例的详细信息,请查看WWDC 2021的相关视频。
附带说明:
而不是元组使用结构。不鼓励将元组作为数据源数组。
https://stackoverflow.com/questions/71529092
复制相似问题