2014-12-16 19 views
5

Ho intenzione di cercare di spiegarlo nel miglior modo possibile.Completamento asincrono Swift per restituire una matrice in classe personalizzata

Sto utilizzando Parse.com e restituisco i dati da una classe di database Parse. Voglio mettere questa chiamata di parse.com nella sua funzione in una classe personalizzata. Il problema che sto avendo è il completamento. Dove va? Ho provato diverse versioni di aggiungerlo alla mia funzione ma non funziona.

Ecco la funzione che prende il nome della classe, il nome della tabella, e descrittore ordinare e restituisce un array:

func queryDataInBackgroundWithBlock(parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor) -> [Any] 

Quando aggiungo il completamento ad esso io uso (che non può essere corretta):

func queryDataInBackgroundWithBlock(parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor, completion: (result: Any)->Void) 

Ora all'interno della funzione io uso il codice Parse.com di uscire e ottenere i dati

query.findObjectsInBackgroundWithBlock { 
     (objects: [AnyObject]!, error: NSError!) -> Void in 
     if error == nil { 

      // Do something with the found objects 
      for object in objects { 
       self.arrayOfObjects.append(object[parseObject]!) 
      } 

     } else { 
      // Log details of the failure 
      println("Error: \(error) \(error.userInfo!)") 
     } 

    } 

Il mio obiettivo qui è quello di inviare i parametri per la mia funzione di classe, ottenere i dati da parse.com e quindi restituire i dati come array dopo la chiamata asincrona

sto provando a chiamare in questo modo:

myClass.queryDataInBackgroundWithBlock("databaseName", parseObject: "columnName", sortDescriptor: orderBy){ 
    (result: Any) in 
    println(result) 
} 

È quasi come se fosse un completamento nidificato. Come posso restituire l'array dopo che è stato completato? Viene trasferito alla funzione che poi lo restituisce, o deve ritornare nel codice annidato, o cosa? Recupera i dati ma il problema è il ritorno DOPO il completamento.

UPDATE: Come ho detto nel commento qui sotto:

query.findObjectsInBackgroundWithBlock({ 
    (objects: [AnyObject]!, error: NSError!) -> Void in 
    if error == nil { 

     // Do something with the found objects 
     for object in objects { 
      self.arrayOfObjects.append(object[parseObject]!) 
     } 

    } else { 
     // Log details of the failure 
     println("Error: \(error) \(error.userInfo!)") 
    } 

}, completion: { 
    //do something here 
}) 

Questo sta tornando l'errore: "completamento argomento extra in call" non sono sicuro di come aggiungere il completamento alla fine del il blocco così ho aggiunto() attorno al blocco e inserito il completamento. Questo è ovviamente sbagliato, ma non sono sicuro di come aggiungere il completamento alla fine del blocco, come Matt ha suggerito

UPDATE 2:

func queryDataInBackgroundWithBlock(parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor) -> [Any]{ 
     var query = PFQuery(className:parseClass) 

     if sortDescriptor.key != "" { 
      query.orderBySortDescriptor(sortDescriptor) 
     } 

     query.findObjectsInBackgroundWithBlock { 
      (objects: [AnyObject]!, error: NSError!) -> Void in 
      if error == nil { 

       // Do something with the found objects 
       for object in objects { 
        self.arrayOfObjects.append(object[parseObject]!!) 
       } 

      } else { 
       // Log details of the failure 
       println("Error: \(error) \(error.userInfo!)") 
      } 

     } 

     return self.arrayOfObjects //<-- needs to move to completion 
    } 
+0

Si prega di copiare e incollare, per intero, la questione, l'implementazione _entire_ di 'func queryDataInBackgroundWithBlock (parseClass: String, parseObject: String, sortDescriptor: NSSortDescriptor, completo: (risultato: qualsiasi) -> Void) '. – matt

+0

messaggio aggiornato – ArchonLight

+0

risposta aggiornata - vedrai che sto semplicemente facendo quello che ho sempre detto che dovresti fare ... – matt

risposta

6

All'interno della funzione queryDataInBackgroundWithBlock si riceve il blocco di completamento sotto il nome completion. Ci vuole un parametro. Quindi l'ultima cosa che fai, dopo avere i dati, è chiamare, consegnandola i dati:

completion(result:myData) 

E poiché query.findObjectsInBackgroundWithBlock stessa è asincrona, sarà necessario fare quella chiamata come l'ultima cosa all'interno il blocco di query.findObjectsInBackgroundWithBlock.

Ti piace questa:

func queryDataInBackgroundWithBlock(
    parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor, 
    completion: (result: Any)->Void) 
{ 
    var query = PFQuery(className:parseClass) 

    if sortDescriptor.key != "" { 
     query.orderBySortDescriptor(sortDescriptor) 
    } 

    query.findObjectsInBackgroundWithBlock { 
     (objects: [AnyObject]!, error: NSError!) -> Void in 
     if error == nil { 

      // Do something with the found objects 
      for object in objects { 
       self.arrayOfObjects.append(object[parseObject]!!) 
      } 

     } else { 
      // Log details of the failure 
      println("Error: \(error) \(error.userInfo!)") 
     } 
     completion(result:self.arrayOfObjects) 
    } 

} 
+0

In realtà non ho bisogno di passare un parametro al completamento, quindi dovrebbe dire completamento:() -> [Qualsiasi]. E findIbjectsInBackground è una funzione di parse.com. Penso che mi stai dicendo di completare il completamento ma non sono sicuro di come farlo – ArchonLight

+0

Sì, devi passare un parametro (in realtà è un argomento). Tu stesso hai dichiarato 'completamento' come se avessi il tipo' (risultato: Qualsiasi) -> Void'. Devi fornire un argomento 'result' quando chiami' completion (...) '. – matt

+0

Guarda il codice che hai citato sopra. _Si_ sta chiamando 'query.findObjectsInBackgroundWithBlock' _con un blocco_. Questo blocco è il tuo codice. Sto dicendo di mettere la chiamata a 'completamento (...)' al suo interno, alla fine, per indicare che il blocco è terminato. – matt