swiftxcodeicloudcloudkitckreference

Get value from CKRecord.Reference in CloudKit


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.


Solution

  • 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)
            }
        }
    }