1

how to skip number of batch result coming from ckqueryCursor from cloudKit, I want to display more cells depend on the number of the existing cells in my table

I did something like that to know how many records and how many batch but I don't know how to tell cloudkit, to display the second batch instead of reload everything...

Parse had Skip ... so what about cloudkit?

    let container = CKContainer.defaultContainer()
    let database = container.publicCloudDatabase
 //count number or records on my database
    let predicate = NSPredicate(value: true)
    let query = CKQuery(recordType: "Products", predicate: predicate)
    query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    database.performQuery(query, inZoneWithID: nil, completionHandler: {
        (results, error) -> Void in
        if error != nil {
            return
        } else {
            let limit = 10
            let APIrequests: Int = ((Int((results?.count)!)  + limit - 1)) / limit
            print("\(APIrequests)") // number of requests we need
            print(results?.count)
        }
    })
Mamoun MK
  • 13
  • 5

1 Answers1

1

CloudKit does not handle this logic within a CKQuery, as you might expect (like a PFQuery does).

CloudKit handles paging using the CKQueryCursor class. You must use instantiate CKQueryOperation directly in order to use queryCursors.

When you perform a CKQueryOperation, in the queryCompletionBlock you must save/cache the queryCursor.

When you would like another page of data, create another CKQueryOperation using initWithCursor and pass the cached queryCursor you saved from your last query.

DBoyer
  • 3,062
  • 4
  • 22
  • 32
  • Thanks for you answer, I did already the first part of you answer with CKQueryCursor and CKQueryOperation, but for save and cache the query cursor , that's new for me, how can I do that, I want just display more cell when I scroll down, because right now I'm bringing every records I have, but I don't want that :S – Mamoun MK Feb 13 '16 at 23:44
  • You can create a property on your ViewController if you want called "queryCursor" or anywhere that will allow you to have this cursor available for the next query. In the queryCompletionBlock, set the property with this cursor. When your user scrolls to the bottom of the table, create a new query with initWithCursor, then just keep repeating this process. – DBoyer Feb 13 '16 at 23:47
  • But how the cursor will know I want display the record number 11 to 20 when I want display more cells ? (because my limit will be 10 in the first batch ) – Mamoun MK Feb 13 '16 at 23:51
  • If you have a limit of 10 on your CKQuery, then the queryCursor will be smart enough to give you the next 10 records. Also note, if the queryCursor is nil, then there is no more data (end of the data set). – DBoyer Feb 13 '16 at 23:52
  • Can you check this what I did here ? https://github.com/mamoun1101/test/tree/master – Mamoun MK Feb 14 '16 at 00:07
  • In the callback of your first query your calling self.queryServer(cursor!), which immediately triggers another query using the cursor, which is not what you want. You are essentially downloading ALL records by using tons of network calls. You need to wait until the user scrolls to the bottom of a tableView before triggering the next 'queryServer' call. – DBoyer Feb 14 '16 at 00:12
  • Yes that's what I'm doing right now, but how can I change my code to do it when the user scroll down and just display the next limit of 10 and not he rest of all the records (Can you create an issue and contribute to my code thanks )? Btw thank you so much for your help – Mamoun MK Feb 14 '16 at 00:18
  • Check out http://stackoverflow.com/questions/20269474/uitableview-load-more-when-scrolling-to-bottom-like-facebook-application, this is a very common question but unrelated to CloudKit. – DBoyer Feb 14 '16 at 00:20
  • Yes I did that too to check when the user scroll down with this code below : override func scrollViewDidEndDecelerating(scrollView: UIScrollView) { let endScrolling = scrollView.contentOffset.y + scrollView.frame.size.height if endScrolling >= scrollView.contentSize.height { // your code goes here } } – Mamoun MK Feb 14 '16 at 00:22
  • in this part :( // your code goes here ) I don't know what do which part of my code I need to put .. – Mamoun MK Feb 14 '16 at 00:24
  • self.queryServer(cursor!) should go there. – DBoyer Feb 14 '16 at 00:28
  • Use of unresolved identifier 'cursor' when I put it there – Mamoun MK Feb 14 '16 at 00:31
  • You need to save the cursor in a property, after your first query so it is available when user scrolls to the bottom. If you are confused about how to do that then you should continue to research how blocks and properties work in iOS. – DBoyer Feb 14 '16 at 00:41