从CloudKit等待数据的闭包

时间:2018-04-22 09:15:05

标签: swift closures cloudkit

我有一个包含一些数据的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)

    }
}

1 个答案:

答案 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以显示数据是否存在。

如果您发现任何错误或需要更多帮助,请告诉我。