Get value from CKRecord.Reference in CloudKit

1.2k views Asked by At

I have 2 recordType: "userDetails" and "request" in which one field in "request" is referencing to "userDetails". I'm wondering if I fetch the record from "request" to get the reference field, and then get the rest of the value from reference that's only available in "userDetails" such as userName, will that be possible? Or is there any way I can achieve that without doing another data fetching?

I tried this:

CKContainer.default().publicCloudDatabase.fetch(withRecordID: CKRecord.ID(recordName: "0A38D024-C191-436E-8622-AE7527805CE8")) { (fetched, error) in
   if fetched != nil {
      let a = fetched?.value(forKey: "requesterReferenceId") as? CKRecord.Reference
      let b = a?.recordID.value(forKey: "userName") as? String
      print(b!)
  }
}

But got an error:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<CKReference 0x600002034280> valueForUndefinedKey:]: this class is not key value coding-compliant for the key userName.'

Appreciate for any helps and suggestions.

1

There are 1 answers

0
Kevvv On BEST ANSWER

I'm assuming you saved the reference like this:

let userDetail = CKRecord(recordType: "UserDetail")
let request = CKRecord(recordType: "Request")
let reference = CKRecord.Reference(recordID: userDetail.recordID, action: .deleteSelf)
request["requesterReferenceId"] = reference as CKRecordValue

Have you tried using the fetched reference as a predicate?

let publicDatabase = CKContainer.default().publicCloudDatabase
publicDatabase.fetch(withRecordID: CKRecord.ID(recordName: "0A38D024-C191-436E-8622-AE7527805CE8")) { (fetched, error) in
    if fetched != nil {
        if let reference = fetched?.value(forKey: "requesterReferenceId") as? CKRecord.Reference {
            let predicate = NSPredicate(format: "recordID == %@", reference)
            let query = CKQuery(recordType: "UserDetail", predicate: predicate)
            let queryOperation = CKQueryOperation(query: query)
            queryOperation.desiredKeys = ["list any keys you want to fetch here"]
            queryOperation.recordFetchedBlock = { (record: CKRecord?) -> Void in
                if let record = record {
                    print(record)
                }
                
            }
            
            queryOperation.queryCompletionBlock = { (cursor: CKQueryOperation.Cursor?, error: Error?) -> Void in
                if let error = error {
                    print(error)
                    return
                }
                
            }
            publicDatabase.add(queryOperation)
        }
    }
}