将完成块添加到 CloudKit 函数
Adding a completion block to a CloudKit function
我的 ViewController 想要显示一些基于 CloudKit 查询的数据。
我的 CloudKit 代码全部在单独的 class 中。 class 有一个名为 loadExpenses() 的函数,它从 CK 获取一些费用实体。
我希望能够从 VC 调用 loadExpenses(),因此我需要函数提供的完成块来从 VC 更新 UI。
这就是 loadExpenses() 的样子:
func loadExpenses() {
let pred = NSPredicate(value: true)
let sort = NSSortDescriptor(key: "creationDate", ascending: true)
let query = CKQuery(recordType: "Expense", predicate: pred)
query.sortDescriptors = [sort]
let operation = CKQueryOperation(query: query)
operation.desiredKeys = ["person", "action", "amount", "timestamp"]
operation.resultsLimit = 50
var newExpenses = [Expense]()
operation.recordFetchedBlock = { (record) in
let recordID = record.recordID
let person = record["person"] as! String
let action = record["action"] as! String
let amount = record["amount"] as! Double
let timestamp = record["timestamp"] as! NSDate
let expense = Expense(person: person, action: action, amount: amount, timestamp: timestamp)
newExpenses.append(expense)
}
// This is the part that needs to be changed
operation.queryCompletionBlock = { [unowned self] (cursor, error) in
dispatch_async(dispatch_get_main_queue()) {
if error == nil {
self.objects = newExpenses
self.tableView.reloadData()
self.refreshRealmDataFromCK()
} else {
let ac = UIAlertController(title: "Fetch failed", message: "There was a problem fetching the list of expenses; please try again: \(error!.localizedDescription)", preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(ac, animated: true, completion: nil)
}
}
}
CKContainer.defaultContainer().privateCloudDatabase.addOperation(operation)
}
显然最后一部分不会执行,考虑到所有那些 self.property 都属于 VC(我保留它们只是为了展示我需要在 VC 中做什么) .
如我所说,我希望能够从 VC 和 get/use 完成块中调用此函数来更新这些属性。我该怎么做?
您需要将块作为参数传递给 loadExpenses()
函数。所以它实际上应该被定义为 loadExpenses(completionBlock:([whatever parameters you need in here])->Void)
.
然后,您可以从 operation.queryCompletionBlock
块中调用传递的 completionBlock
块(使用适当的参数)。
编辑:
所以这当然没有经过测试,但您可以试一试:
func loadExpenses(completionBlock:([Expense])->Void) {
let pred = NSPredicate(value: true)
let sort = NSSortDescriptor(key: "creationDate", ascending: true)
let query = CKQuery(recordType: "Expense", predicate: pred)
query.sortDescriptors = [sort]
let operation = CKQueryOperation(query: query)
operation.desiredKeys = ["person", "action", "amount", "timestamp"]
operation.resultsLimit = 50
var newExpenses = [Expense]()
operation.recordFetchedBlock = { (record) in
let recordID = record.recordID
let person = record["person"] as! String
let action = record["action"] as! String
let amount = record["amount"] as! Double
let timestamp = record["timestamp"] as! NSDate
let expense = Expense(person: person, action: action, amount: amount, timestamp: timestamp)
newExpenses.append(expense)
}
// This is the part that needs to be changed
operation.queryCompletionBlock = { [unowned self] (cursor, error) in
completionBlock(newExpenses)
}
CKContainer.defaultContainer().privateCloudDatabase.addOperation(operation)
}
然后这样称呼它:
loadExpenses({ (newExpenses:[Expense]) -> Void in {
dispatch_async(dispatch_get_main_queue()) {
if error == nil {
self.objects = newExpenses
self.tableView.reloadData()
self.refreshRealmDataFromCK()
} else {
let ac = UIAlertController(title: "Fetch failed", message: "There was a problem fetching the list of expenses; please try again: \(error!.localizedDescription)", preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(ac, animated: true, completion: nil)
}
}
}
我的 ViewController 想要显示一些基于 CloudKit 查询的数据。
我的 CloudKit 代码全部在单独的 class 中。 class 有一个名为 loadExpenses() 的函数,它从 CK 获取一些费用实体。
我希望能够从 VC 调用 loadExpenses(),因此我需要函数提供的完成块来从 VC 更新 UI。
这就是 loadExpenses() 的样子:
func loadExpenses() {
let pred = NSPredicate(value: true)
let sort = NSSortDescriptor(key: "creationDate", ascending: true)
let query = CKQuery(recordType: "Expense", predicate: pred)
query.sortDescriptors = [sort]
let operation = CKQueryOperation(query: query)
operation.desiredKeys = ["person", "action", "amount", "timestamp"]
operation.resultsLimit = 50
var newExpenses = [Expense]()
operation.recordFetchedBlock = { (record) in
let recordID = record.recordID
let person = record["person"] as! String
let action = record["action"] as! String
let amount = record["amount"] as! Double
let timestamp = record["timestamp"] as! NSDate
let expense = Expense(person: person, action: action, amount: amount, timestamp: timestamp)
newExpenses.append(expense)
}
// This is the part that needs to be changed
operation.queryCompletionBlock = { [unowned self] (cursor, error) in
dispatch_async(dispatch_get_main_queue()) {
if error == nil {
self.objects = newExpenses
self.tableView.reloadData()
self.refreshRealmDataFromCK()
} else {
let ac = UIAlertController(title: "Fetch failed", message: "There was a problem fetching the list of expenses; please try again: \(error!.localizedDescription)", preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(ac, animated: true, completion: nil)
}
}
}
CKContainer.defaultContainer().privateCloudDatabase.addOperation(operation)
}
显然最后一部分不会执行,考虑到所有那些 self.property 都属于 VC(我保留它们只是为了展示我需要在 VC 中做什么) .
如我所说,我希望能够从 VC 和 get/use 完成块中调用此函数来更新这些属性。我该怎么做?
您需要将块作为参数传递给 loadExpenses()
函数。所以它实际上应该被定义为 loadExpenses(completionBlock:([whatever parameters you need in here])->Void)
.
然后,您可以从 operation.queryCompletionBlock
块中调用传递的 completionBlock
块(使用适当的参数)。
编辑:
所以这当然没有经过测试,但您可以试一试:
func loadExpenses(completionBlock:([Expense])->Void) {
let pred = NSPredicate(value: true)
let sort = NSSortDescriptor(key: "creationDate", ascending: true)
let query = CKQuery(recordType: "Expense", predicate: pred)
query.sortDescriptors = [sort]
let operation = CKQueryOperation(query: query)
operation.desiredKeys = ["person", "action", "amount", "timestamp"]
operation.resultsLimit = 50
var newExpenses = [Expense]()
operation.recordFetchedBlock = { (record) in
let recordID = record.recordID
let person = record["person"] as! String
let action = record["action"] as! String
let amount = record["amount"] as! Double
let timestamp = record["timestamp"] as! NSDate
let expense = Expense(person: person, action: action, amount: amount, timestamp: timestamp)
newExpenses.append(expense)
}
// This is the part that needs to be changed
operation.queryCompletionBlock = { [unowned self] (cursor, error) in
completionBlock(newExpenses)
}
CKContainer.defaultContainer().privateCloudDatabase.addOperation(operation)
}
然后这样称呼它:
loadExpenses({ (newExpenses:[Expense]) -> Void in {
dispatch_async(dispatch_get_main_queue()) {
if error == nil {
self.objects = newExpenses
self.tableView.reloadData()
self.refreshRealmDataFromCK()
} else {
let ac = UIAlertController(title: "Fetch failed", message: "There was a problem fetching the list of expenses; please try again: \(error!.localizedDescription)", preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(ac, animated: true, completion: nil)
}
}
}