我有一个包含一些数据的CloudKit数据库。通过按下按钮,我的应用程序应检查数据库中是否存在某些数据。问题是所有进程在我的应用程序获得搜索结果之前结束。我发现这个有用Answer,据说它使用了闭包。
我试着遵循相同的结构,但是Swift问我参数,我在这里很快就迷路了。
有人可以帮助我吗?谢谢你的帮助
func reloadTable() {
self.timePickerView.reloadAllComponents()
}
func getDataFromCloud(completionHandler: @escaping (_ records: [CKRecord]) -> Void) {
print("I begin asking process")
var listOfDates: [CKRecord] = []
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "Riservazioni", predicate: predicate)
let queryOperation = CKQueryOperation(query: query)
queryOperation.resultsLimit = 20
queryOperation.recordFetchedBlock = { record in
listOfDates.append(record)
}
queryOperation.queryCompletionBlock = { cursor, error in
if error != nil {
print("error")
print(error!.localizedDescription)
} else {
print("NO error")
self.Array = listOfDates
completionHandler(listOfDates)
}
}
}
var Array = [CKRecord]()
func generateHourArray() {
print("generate array")
for hour in disponibleHours {
let instance = CKRecord(recordType: orderNumber+hour)
if Array.contains(instance) {
disponibleHours.remove(at: disponibleHours.index(of: hour)!)
}
}
}
func loadData() {
timePickerView.reloadAllComponents()
timePickerView.isHidden = false
}
@IBAction func checkDisponibility(_ sender: Any) {
if self.timePickerView.isHidden == true {
getDataFromCloud{ (records) in
print("gotData")
self.generateHourArray()
self.loadData()
}
print(Array)
}
}
答案 0 :(得分:2)
我很难理解你的代码以及CloudKit元素适合它的位置,所以我将尝试给出一个通用的答案,希望它仍能帮助你。
让我们从我们要调用的函数开始获取我们的CloudKit数据,假设我们正在获取一个人列表。
func getPeople() {
}
到目前为止这很简单,现在让我们添加CloudKit代码。
func getPeople() {
var listOfPeople: [CKRecord] = [] // A place to store the items as we get them
let query = CKQuery(recordType: "Person", predicate: NSPredicate(value: true))
let queryOperation = CKQueryOperation(query: query)
queryOperation.resultsLimit = 20
// As we get each record, lets store them in the array
queryOperation.recordFetchedBlock = { record in
listOfPeople.append(record)
}
// Have another closure for when the download is complete
queryOperation.queryCompletionBlock = { cursor, error in
if error != nil {
print(error!.localizedDescription)
} else {
// We are done, we will come back to this
}
}
}
现在我们有了人员列表,但是一旦CloudKit完成,我们想要返回这个。正如你所说,我们想要使用一个闭包。让我们在函数定义中添加一个。
func getPeople(completionHandler: @escaping (_ records: [CKRecord]) -> Void) {
...
}
以上添加了完成处理程序。我们要传递给调用者的参数是记录,因此我们将其添加到定义中。我们不希望任何人回复我们的完成处理程序,因此我们期望返回值为Void
。您可能需要一个布尔值作为成功消息,但这完全取决于项目。
现在让我们将整个事物捆绑在一起。在我说我们会回来的那一行,您现在可以用以下内容替换评论:
completionHandler(listOfPeople)
一旦CloudKit完成,这将会将人员列表发送给调用者。我已经在下面展示了一个调用此功能的人的例子。
getPeople { (records) in
// This code wont run until cloudkit is finished fetching the data!
}
要记住的是CloudKit API在哪个线程上运行。如果它在后台线程上运行,那么回调也将在后台线程上 - 因此请确保您不在完成处理程序中进行任何UI更改(或将其移动到主线程)。
您可以对此代码进行许多改进,并使其适应您自己的项目,但它应该为您提供一个开始。马上,Id图像您需要将完成处理程序参数更改为Bool
以显示数据是否存在。
如果您发现任何错误或需要更多帮助,请告诉我。