2016-02-14 3 views
1

My ViewController хочет отобразить некоторые данные на основе запроса CloudKit.Добавление блока завершения к функции CloudKit

Мой код CloudKit находится в отдельном классе. Этот класс имеет функцию loadExpenses(), которая извлекает некоторые объекты затрат из CK.

Я хочу иметь возможность вызвать loadExpenses() из VC, поэтому мне нужен блок завершения, предоставляемый функцией для обновления пользовательского интерфейса от VC.

Это то, что 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 и получить/использовать блок завершения для обновления этих свойств. Как мне это сделать?

ответ

1

Вам необходимо передать блок в качестве параметра функции loadExpenses(). Поэтому на самом деле должно быть определено что-то вроде loadExpenses(completionBlock:([whatever parameters you need in here])->Void).

Затем вы можете вызвать пройденный блок completionBlock (с соответствующими параметрами) из блока operation.queryCompletionBlock.

EDIT:

Так что это не тестируется на всех, конечно, но вы могли бы дать ему шанс:

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) 
     } 
    } 
} 
+0

Благодарю. Не могли бы вы отредактировать свой ответ, указав примерный код? –

+0

Я попытался собрать код для вас, см. Отредактированный ответ –

+0

Спасибо. Сейчас ясно. –

Смежные вопросы