向 CloudKit 函数添加完成块

Posted

技术标签:

【中文标题】向 CloudKit 函数添加完成块【英文标题】:Adding a completion block to a CloudKit function 【发布时间】:2016-02-14 11:57:01 【问题描述】:

我的 ViewController 想要显示一些基于 CloudKit 查询的数据。

我的 CloudKit 代码都在一个单独的类中。该类有一个名为 loadExpenses() 的函数,可以从 CK 获取一些 Expenses 实体。

我希望能够从 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 调用此函数并获取/使用完成块来更新这些属性。我该怎么做?

【问题讨论】:

【参考方案1】:

您需要将块作为参数传递给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)
        
    

【讨论】:

谢谢。您能否提供一些示例代码来编辑您的答案? 我尝试为您整理一些代码,请参阅编辑后的答案

以上是关于向 CloudKit 函数添加完成块的主要内容,如果未能解决你的问题,请参考以下文章

swift Swift - CloudKit - 向一个或多个应用添加或共享容器

IOS swift中的完成块

无法访问 CloudKit 仪表板和容器

是否可以将外部数据添加到 CloudKit?

如何批准上传到 CloudKit

CloudKit 重新索引数据需要很长时间