23

I need to query all the record types, without any filtering. I tried two ways:

let query = CKQuery(recordType: "Pm", predicate: nil)
let query = CKQuery(recordType: "Pm", predicate: NSPredicate(format: ""))

I got error:

'NSInvalidArgumentException', reason: 'Unable to parse the format string ""'

How to do?

Matteo
  • 37,680
  • 11
  • 100
  • 115
János
  • 32,867
  • 38
  • 193
  • 353

2 Answers2

38

You can't perform a query without a predicate, but NSPredicate does have a method just for this, and in Swift it's used through the initializer:

init(value: Bool) -> NSPredicate // return predicates that always evaluate to true/false

Usage is as follows.

let predicate = NSPredicate(value: true)
Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281
  • hi mick do you know if there is another way to write the public database as an administrator, to seed and maintain data, without requiring an icloud login? full question: http://stackoverflow.com/questions/36808601/seed-and-maintain-cloudkit-public-database-still-requires-icloud-login – Crashalot Apr 23 '16 at 08:52
  • According to CKQuery API Reference: "Predicates are based on a format string. You cannot use value or block-based predicates." I don't think it was always like this, but currently this answer no longer works. – Mercutio May 29 '17 at 23:03
  • 1
    @JamesLingo That is incorrect. When referring to "value or block-based predicates," Apple is referring to predicates based on closures (e.g. `CKQuery(recordType: "Pm", predicate: { $0.id == 42 })`). Any valid NSPredicate is supported, and `NSPredicate(value:)` is provided as a means of creating an NSPredicate that always either evaluates `true` or `false`. – Mick MacCallum May 30 '17 at 12:15
  • @MickMacCallum The documentation specifically says you need to use format strings and that you can't use block **or** value. If you go a few paragraphs down from my last quote in the CKQuery API ref: "To retrieve all records of a given type, use the TRUEPREDICATE expression as shown in Listing 8." I am currently reviewing some of my older code that used to work with 'value: true' and I had to update it to get it to pass my unit tests. Is NSPredicate(value:) still working with CKQuery for you, and if so are you using swift 3.0? – Mercutio May 30 '17 at 23:45
20

To get all your records, you will need to use this as the predicate for your CKQuery:

[NSPredicate predicateWithFormat:@"TRUEPREDICATE"]

or, in Swift:

NSPredicate(format: "TRUEPREDICATE")

This effectively works like not having any predicate.

zdestiny
  • 542
  • 3
  • 10
  • 3
    This is the solution Apple recommends in the documentation. There's probably nothing wrong with your answer but given 2 solutions the documented one should be preferred – Yariv Nissim May 20 '15 at 22:57
  • 2
    Just a note if anyone had a problem with this: I had to enable an index on the Record's id field in the CloudKit dashboard. I have no idea why, but when I did that the @"TRUEPREDICATE" format started to work. The error I got stated: "Field '___recordID' is not marked queryable". Here's the Stack that I found regarding this issue: http://stackoverflow.com/questions/29142717/field-recordid-is-not-marked-queryable. – KellyHuberty Aug 28 '16 at 19:17