2015-07-19 1 views
6

Я пытаюсь загрузить партию записей из моей открытой базы данных iCloud с помощью CloudKit и курсора. Код работает отлично для первых 3 исполнений, независимо от того, как установлен параметр resultsLimit, но четвертый блок завершения никогда не выполняется. Если resultsLimit не установлен, я получаю 300 записей, если он установлен на 50, я получаю 150, если он установлен на 5, я получаю 15 ...CKQueryOperation queryCompletionBlock работает только 3 раза

Сообщается об ошибке, и блок кажется добавленным, но никогда не выполняется. Платформа OS X. Вот код в вопросе:

 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) 

А вот результаты из консоли -

459013587628,012 0 459013587628,621 1 459013587628,863 2 459013587629,113 3 459013587629,339 4 Comp блок под названием с нуля добавили следующую выборку 459013587828,552 5 459013587828,954 6 459013587829,198 7 459013587829,421 8 4 59013587829.611 9 компа блок вызывается с нулевым добавлены следующей выборкой 459013587997,084 10 459013587997,479 11 459013587997,74 12 459013587997,98 13 459013587998,207 14

Большое число только время между вызовами recordFetchedBlock с вторым номером является счетчиком раз, когда этот блок был вызван.

Я в тупике ... любые идеи о том, как действовать дальше? О, контейнер и publicDatabase являются переменными класса и инициализированы перед запуском фрагмента кода выше.

ответ

5

То, как вы определяете nextOp внутри своей области queryCompletionBlock, вызывает проблему после трех итераций этого блока. Если вы нарушите создание CKQueryOperation в своем собственном методе, ваша проблема исчезнет.

Вот код:

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

Спасибо Дэйв извинения за то, что так долго, чтобы ответить, но ваш реакция мертва. Как только я переместил это в свою собственную функцию, запрос работал отлично. – Oswaldt

+1

Спасибо! Однако, похоже, операция.cursor = курсор не запускает операцию с помощью курсора; вместо этого, используя операцию = CKQueryOperation (курсор: курсор) работал для меня - мысли? – hyouuu

+0

Ahh, хороший улов. Документы действительно говорят: «Когда вы используете курсор, содержимое свойства запроса игнорируется», поэтому я соответствующим образом обновил образец кода. –

0

Это может быть другой подход (уже обновлен до Swift 3).

Он не останавливается после третьей итерации, но продолжается до конца

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) 

Я успешно использовать его для извлечения сотни записей из CloudKit