1

This is the case - I'm using a simple UITableView that renders records from the CloudKit publicDB. When I run the app, the query operation returns for example returns 2 results (that's all it has currently).

My table view has a refresh control and when I pull to refresh I got zero results, if I continue to do reloads, eventually a result might come out but now always.

The same thing happens with more results as well, I used to have CKLocation type which I queried and the response was always different without any common sense

Some example code (the predicate in this case is TRUEPREDICATE - nothing fancy):

    let sort = NSSortDescriptor(key: "creationDate", ascending: false)        
    let query = CKQuery(recordType: "Tests", predicate: DiscoveryMode.getPredicate())
    query.sortDescriptors = [sort]

    var operation = CKQueryOperation(query: query)
    if lastCursor != nil {
        operation = CKQueryOperation(cursor: lastCursor)
    }

    operation.resultsLimit = 15
    operation.recordFetchedBlock = recordFetchBlock
    operation.queryCompletionBlock = { [weak self] (cursor:CKQueryCursor!, error:NSError!) in

        if cursor != nil {
             self!.lastCursor = cursor
        }

        dispatch_async(dispatch_get_main_queue(), { () -> Void in

            Misc.hideLoadingInView(view: self!.view)

            self!.tableView.reloadData()
            self!.refreshControl.endRefreshing()

            if error != nil {
                Misc.showErrorInView(view: self!.view, message: error.localizedDescription)
            }
        })
    }

    CloudKit.sharedInstance.publicDB.addOperation(operation)

All the recordFetchBlock does is to add objects to a mutable array that the table view uses as dataSource.

I'm new to CloudKit and I'm puzzled is this by design (not returning all the results but some random) or I'm doing something wrong?

peerless
  • 558
  • 3
  • 11

2 Answers2

1

I see that you are using a cursor. because of that the 2nd call will start at the point where the first call ended. You have a resultsLimit of 15. When using a cursor, you will only receive records the 2nd time you execute the query if there were more than 15 records. To test if this is the issue just comment out the line where you set the cursor: operation = CKQueryOperation(cursor: lastCursor)

Edwin Vermeer
  • 13,017
  • 2
  • 34
  • 58
  • Hm, interesting, afaik the cursor is only returned if there is more results than the provided limit. I never thought this could be the case (didnt debug the cursor), did what you've suggested and now its looks like working... very strange... If that cursor check is not to be trusted, how could I know if there are more results than the limit? – peerless Jun 30 '15 at 10:34
  • Hm, nope, still has issue... its not the cursor – peerless Jun 30 '15 at 10:37
  • Ah.. you are right... The cursor should have been nil... But still you should always set it to the returned value in the queryCompletionBlock. Otherwise it will never go back to nil and keeps reeding from the previous cursor if there was any – Edwin Vermeer Jun 30 '15 at 10:51
  • Looks like this is something with the CLLocation predicates: `CURSOR: nil PREDICATE: distanceToLocation:fromLocation:(location, <+42.68164669,+23.31165791>) < 500 - record with distance = 0.427553534524166 km. - record with distance = 0.427553534524166 km. CURSOR: nil PREDICATE: distanceToLocation:fromLocation:(location, <+42.67792387,+23.29822540>) < 500 - record with distance = 1.34367205197676 km. - record with distance = 1.34367205197676 km. CURSOR: nil PREDICATE: distanceToLocation:fromLocation:(location, <+42.66631226,+23.28874111>) < 500 ??? - no records` – peerless Jun 30 '15 at 11:05
  • but your location is different. I would think that your records would then be located outside your selection. What happens when you increase your selection to something like 5000? – Edwin Vermeer Jun 30 '15 at 12:56
  • I thought so at first but then I calculated the location. I'm requesting radius of 500km and the response locations are at distance of maximum 10km. The locations I'm using are taken by me on places I'm sure have no more than 20km in distance. – peerless Jun 30 '15 at 14:01
  • when I enter the first 2 locations at http://www.movable-type.co.uk/scripts/latlong.html then I get back that these are 1173 km apart!? Hmm.. on the map its about 1KM – Edwin Vermeer Jun 30 '15 at 14:32
  • I'll do some more tests today and see whats going on. – peerless Jul 01 '15 at 05:33
0

I found the issue, I was trying to do (in the NSPredicate) a radius with a value I read somewhere is in kilometers. Therefore I was trying to query records within 500 meters instead of 500 kilometers and the GPX file I'm using in the simulator has multiple records with a larger distance. Since it simulates movement, that was the reason not to get consistent results.

Now, when I'm using a proper value for the radius all seems to be just fine!

peerless
  • 558
  • 3
  • 11