2015-07-19 13 views
6

Sto provando a scaricare un batch di record dal mio database pubblico iCloud utilizzando CloudKit e il cursore. Il codice funziona bene per le prime 3 esecuzioni, indipendentemente da come viene impostato il limite dei risultati, ma il 4 ° blocco di completamento non viene mai eseguito. Se setLimit non è impostato ottengo 300 record, se è impostato su 50 ottengo 150, se è impostato su 5 ottengo 15 ...CKQueryOperation queryCompletionBlock viene eseguito solo 3 volte

Nessun errore viene segnalato e il blocco sembra essere aggiunto ma non viene mai eseguito. Piattaforma è OS X. Ecco il codice in questione:

 let queryOp = CKQueryOperation(query: query) 
     queryOp.recordFetchedBlock = self.fetchedDetailRecord 
     queryOp.resultsLimit = 5 
     queryOp.queryCompletionBlock = { [weak self] 
      (cursor: CKQueryCursor!, error: NSError!) -> Void in 
      println("comp block called with \(cursor) \(error)") 
      if error != nil { 
      println("Error on fetch \(error.userInfo)") 
      } else { 
      if cursor != nil { 
       let nextOp = CKQueryOperation(cursor: cursor) 
       nextOp.recordFetchedBlock = self!.fetchedDetailRecord 
       nextOp.queryCompletionBlock = queryOp.queryCompletionBlock 
       nextOp.resultsLimit = 5 
       self!.publicDatabase?.addOperation(nextOp) 
       println("added next fetch") 
      } else { 
       self!.fileHandle!.closeFile() 
       self!.exportProgressIndicator.stopAnimation(self) 
      } 
      } 
     } 

     self.publicDatabase?.addOperation(queryOp) 

Ed ecco i risultati dalla console -

459013587628,012 0 459013587628,621 1 459013587628,863 2 459013587629,113 3 459013587629,339 4 blocco bozzetto chiamati con nil aggiunta successiva recuperare 459013587828,552 5 459013587828,954 6 459013587829,198 7 459013587829,421 8 4 blocco 59013587829.611 9 bozzetto chiamato con nil aggiunta successiva recuperare 459013587997,084 10 459013587997,479 11 459013587997,74 12 459013587997,98 13 459013587998,207 14

Il numero grande è proprio il tempo tra chiamate alla recordFetchedBlock con il secondo numero è il conteggio di volte in cui è stato chiamato il blocco.

Sono perplesso ... qualche idea su come procedere? Oh, container e publicDatabase sono variabili di classe e inizializzate prima di eseguire lo snippet di codice sopra.

risposta

5

Il modo in cui si sta definendo nextOp all'interno della queryCompletionBlock scope sta causando un problema dopo tre iterazioni di quel blocco. Se si interrompe la creazione di CKQueryOperation nel proprio metodo, il problema scompare.

Ecco il codice:

func fetchedDetailRecord(record: CKRecord!) -> Void { 
    println("Retrieved record: \(record)") 
} 

func createQueryOperation(cursor: CKQueryCursor? = nil) -> CKQueryOperation { 
    var operation:CKQueryOperation 
    if (cursor != nil) { 
     operation = CKQueryOperation(cursor: cursor!) 
    } else { 
     operation = CKQueryOperation(query: CKQuery(...)) 
    } 
    operation.recordFetchedBlock = self.fetchedDetailRecord 
    operation.resultsLimit = 5 
    operation.queryCompletionBlock = { [weak self] 
     (cursor: CKQueryCursor!, error: NSError!) -> Void in 
     println("comp block called with \(cursor) \(error)") 
     if error != nil { 
      println("Error on fetch \(error.userInfo)") 
     } else { 
      if cursor != nil { 
       self!.publicDatabase?.addOperation(self!.createQueryOperation(cursor: cursor)) 
       println("added next fetch") 
      } else { 
       self!.fileHandle!.closeFile() 
       self!.exportProgressIndicator.stopAnimation(self) 
      } 
     } 
    } 
    return operation 
} 

func doQuery() { 
    println("Querying records...") 
    self.publicDatabase?.addOperation(createQueryOperation()) 
} 
+0

Grazie Dave, scuse per così tanto tempo per rispondere, ma la vostra la risposta è morta. Una volta che l'ho spostato nella sua funzione, la query ha funzionato perfettamente. – Oswaldt

+1

Grazie! Tuttavia, sembra operation.cursor = cursor non fa in modo che l'operazione inizi con il cursore; invece usando operation = CKQueryOperation (cursore: cursore) ha funzionato per me - pensieri? – hyouuu

+0

Ah, buona presa. I documenti dicono in realtà "Quando si utilizza un cursore, il contenuto della proprietà della query viene ignorato", così ho aggiornato l'esempio di codice di conseguenza. –

0

Questo potrebbe essere un altro approccio (già aggiornato alla Swift 3).

Non si arresta dopo terza iterazione, ma continua fino alla fine

var queryOp = CKQueryOperation(query: query) 
queryOp.recordFetchedBlock = self.fetchedARecord 
queryOp.resultsLimit = 5 
queryOp.queryCompletionBlock = { [weak self] (cursor : CKQueryCursor?, error : Error?) -> Void in 
    print("comp block called with \(cursor) \(error)") 

    if cursor != nil { 
     let nextOp = CKQueryOperation(cursor: cursor!) 
     nextOp.recordFetchedBlock = self!.fetchedARecord 
     nextOp.queryCompletionBlock = queryOp.queryCompletionBlock 
     nextOp.resultsLimit = queryOp.resultsLimit 

     //this is VERY important 
     queryOp = nextOp 

     self!.publicDB.add(queryOp) 
     print("added next fetch") 
    } 

} 

self.publicDB.add(queryOp) 

Io con successo lo uso per recuperare centinaia di record da CloudKit

Problemi correlati