Queries and predicates doubt

Ask a question here. It may wind up in the FAQ on the plugin homepage.
pistoleta
Posts: 16
Joined: Fri Nov 06, 2020 12:11 pm

Queries and predicates doubt

Post by pistoleta »

I have records of type "Image" and Im trying to query some of those records on a query.
Those records have custom names "image1" , "image2".....

So I'm trying to query them by the register name, and I've read you are supposed to do that using recordID in the predicate.
But when I try to do it I get the exception:
"Code 12: Field ___recordID has a value type of REFERENCE and cannot by queried using filter value type STRING"

Then I've found this:
https://developer.apple.com/forums/thread/35552

Says how to query using references, but I dont know if this is possible to do through the API.
How am I supposed to create a predicate that contains references?

Btw im trying to fetch several ones so im using the clause reccordID IN { 'xxxx' , 'yyyy'..... }

Thanks

admin
Site Admin
Posts: 49
Joined: Thu Mar 19, 2020 8:52 pm

Re: Queries and predicates doubt

Post by admin »

Yeah, that's not a use case I've tested yet. I'll read up on the issue and reply back later with either a working string query, or a plan to update the API.

pistoleta
Posts: 16
Joined: Fri Nov 06, 2020 12:11 pm

Re: Queries and predicates doubt

Post by pistoleta »

I think the problem is we can just use predicates as strings. But seeing how they query a register by it's name we need to use a registerID var (which is a CKReference) inside the predicate, and I guess we can't.

This is how they do it:

Code: Select all

let reference = CKReference(recordID: userID, action: .None)
let predicate = NSPredicate(format: "creatorUserRecordID == %@", reference)
let query = CKQuery(recordType: "Species", predicate: predicate)
I just created a new field in the Image registers called 'name' and im querying using it, this way it works.

admin
Site Admin
Posts: 49
Joined: Thu Mar 19, 2020 8:52 pm

Re: Queries and predicates doubt

Post by admin »

Found some time to experiment with this today. Looks like you are right. Not every predicate can be expressed as a pure string.

I was feeling confident there would be an underlying string representation for a CKReference, since the "%@" format specifier is used in string substitutions. As in: NSLog(@"%@", error); which logs the string representation of the error to the console. But there appears to be some "magic" in NSPredicate that "ingests" the CKReference itself.

For instance, the following (objective-c) examples are NOT equivalent to each other

Example 1 - CKReference direct substitution (works)

Code: Select all

CKReference* reference = [[CKReference alloc] initWithRecordID:[[CKRecordID alloc] initWithRecordName:@"09783CC3-6CAF-4D6D-8B2E-D17348A4BC52"] action:CKReferenceActionNone];
NSPredicate* pred = [NSPredicate predicateWithFormat:@"RecordToReference == %@", reference];
NSLog(@"predicate is: %@", [pred predicateFormat]);

// Prints (without quotes)
// RecordToReference == <CKReference: 0x6000002409a0; recordID=<CKRecordID: 0x600000240a20; recordName=09783CC3-6CAF-4D6D-8B2E-D17348A4BC52, zoneID=_defaultZone:__defaultOwner__>>
Example 2 - Covert CKReference to string - does not work

Code: Select all

CKReference* reference = [[CKReference alloc] initWithRecordID:[[CKRecordID alloc] initWithRecordName:@"09783CC3-6CAF-4D6D-8B2E-D17348A4BC52"] action:CKReferenceActionNone];
NSString* str = [NSString stringWithFormat:@"%@", reference];
NSPredicate* pred = [NSPredicate predicateWithFormat:@"RecordToReference == %@", str];
NSLog(@"predicate is: %@", [pred predicateFormat]);

// Prints (with quotes)
// predicate is: RecordToReference == "<CKReference: 0x6000002451a0; recordID=<CKRecordID: 0x600000245220; recordName=09783CC3-6CAF-4D6D-8B2E-D17348A4BC52, zoneID=_defaultZone:__defaultOwner__>>"
I'm glad you have a workaround. Support for this in the plugin is a bit tricky. Since the user can supply any format string, and any values for substitution, the function will have to be variadic, and I'll need to marshal an array type-tokens and pointers to values down to objective-c and reconstruct the value types on the other end. Any reference types that inherit from NSObject should just work, but I won't be able to prevent anyone from sending garbage down to native-land. Lots of work for a one-off but it can be done.

We're pretty busy getting a GameCenter plugin up and running, so I don't know what the timeline would be for getting this working. But let me know how important this is to you. If there's enough demand we can fast track it.

pistoleta
Posts: 16
Joined: Fri Nov 06, 2020 12:11 pm

Re: Queries and predicates doubt

Post by pistoleta »

No its not important, I simply created a queryable field in the register and I use that field to retreive them in the query.
If another use case comes up where this is an inconvenience I will let you know but for the moment it's fine.
Thanks

Post Reply