关闭等待来自 CloudKit 的数据
Closures for waiting data from CloudKit
我有一个包含一些数据的 CloudKit 数据库。通过按下按钮,我的应用程序应该检查数据库中是否存在某些数据。问题是所有进程在我的应用程序获得搜索结果之前就结束了。我发现这很有用 ,据说它使用闭包。
我试图遵循相同的结构,但 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)
}
}
我很难理解你的代码以及 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
}
}
}
现在我们有了人员名单,但我们想 return 一旦 CloudKit 完成。正如您所说的那样,我们想为此使用闭包。让我们在函数定义中添加一个。
func getPeople(completionHandler: @escaping (_ records: [CKRecord]) -> Void) {
...
}
上面添加了一个完成处理程序闭包。我们要传递给调用者的参数是记录,因此我们将其添加到定义中。我们不期望任何人响应我们的完成处理程序,因此我们期望 return 值为 Void
。您可能需要此处的布尔值作为成功消息,但这完全取决于项目。
现在让我们把整个事情联系起来。在我说过我们会回来的那一行,您现在可以将评论替换为:
completionHandler(listOfPeople)
这会在 CloudKit 完成后立即将人员列表发送给呼叫者。我在下面展示了一个调用此函数的示例。
getPeople { (records) in
// This code wont run until cloudkit is finished fetching the data!
}
需要注意的是,CloudKit API 在哪个线程上运行。如果它在后台线程上运行,那么回调也将在后台线程上运行 - 因此请确保您没有对完成处理程序进行任何 UI 更改(或将其移至主线程)。
您可以对此代码进行很多改进,并使其适应您自己的项目,但它应该给您一个开始。马上,Id image 您将想要将完成处理程序参数更改为 Bool
以显示数据是否存在。
如果您发现任何错误或需要更多帮助,请告诉我。
我有一个包含一些数据的 CloudKit 数据库。通过按下按钮,我的应用程序应该检查数据库中是否存在某些数据。问题是所有进程在我的应用程序获得搜索结果之前就结束了。我发现这很有用
我试图遵循相同的结构,但 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)
}
}
我很难理解你的代码以及 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
}
}
}
现在我们有了人员名单,但我们想 return 一旦 CloudKit 完成。正如您所说的那样,我们想为此使用闭包。让我们在函数定义中添加一个。
func getPeople(completionHandler: @escaping (_ records: [CKRecord]) -> Void) {
...
}
上面添加了一个完成处理程序闭包。我们要传递给调用者的参数是记录,因此我们将其添加到定义中。我们不期望任何人响应我们的完成处理程序,因此我们期望 return 值为 Void
。您可能需要此处的布尔值作为成功消息,但这完全取决于项目。
现在让我们把整个事情联系起来。在我说过我们会回来的那一行,您现在可以将评论替换为:
completionHandler(listOfPeople)
这会在 CloudKit 完成后立即将人员列表发送给呼叫者。我在下面展示了一个调用此函数的示例。
getPeople { (records) in
// This code wont run until cloudkit is finished fetching the data!
}
需要注意的是,CloudKit API 在哪个线程上运行。如果它在后台线程上运行,那么回调也将在后台线程上运行 - 因此请确保您没有对完成处理程序进行任何 UI 更改(或将其移至主线程)。
您可以对此代码进行很多改进,并使其适应您自己的项目,但它应该给您一个开始。马上,Id image 您将想要将完成处理程序参数更改为 Bool
以显示数据是否存在。
如果您发现任何错误或需要更多帮助,请告诉我。