4 Replies
      Latest reply on Mar 25, 2020 2:21 AM by ramart
      Misbo Level 1 Level 1 (0 points)

        I have a situation where a CloudKit record is not being returned by a query (and also doesn't appear in the CloudKit dashboard), but it exists when fetching it by it's ID.

         

        The record was added days ago, so it really should have been indexed.

         

        The record ID metadata index has always been set for the record type.

         

        The query I use is fetching all records for a particular record type in a custom zone.

         

        Strangely, when I search for the record in the dashboard and select it, the record name field is blank on the detail panel.

         

        It's very peculiar, and very concerning!

         

        Anyone have any ideas?

        • Re: CloudKit record exists (added days ago), does not get returned by query but can be fetched by ID
          PBK Level 7 Level 7 (3,585 points)

          Show us your code for the original save, the fetch and the query.  Include the specifications for the CKRecordZoneID, CKQuery, NSPredicate, CKDatabase, CKContainer and CKRecordID for the query and the fetch and the original save command (CKModifyRecordsOperation?).

            • Re: CloudKit record exists (added days ago), does not get returned by query but can be fetched by ID
              Misbo Level 1 Level 1 (0 points)

              I should say that most other records work absolutely fine. This is an anomaly with a handful of records. All records were created days ago and there should be nothing special about the ones that are missing. They have just suddently started to not be returned.

               

              Here's is some very stripped down code that is used to save and query the data:

               

              let defaultContainer = CKContainer(identifier: "iCloud.com.company.app")
              let privateDatabase = defaultContainer.privateCloudDatabase
              let operationQueue = NSOperationQueue()
              let recordZoneID = CKRecordZoneID(zoneName: "AttachmentsZone", ownerName: CKOwnerDefaultName)
              let attachmentRecordType = "Attachment"
              
              //
              // Save
              //
              
              // Create attachment record
              let recordID = CKRecordID(recordName: "attachment1.jpg", zoneID: recordZoneID)
              let attachmentRecord = CKRecord(recordType: attachmentRecordType, recordID: recordID)
              // ... Set other attributes
              
              // Save operation
              let operation = CKModifyRecordsOperation(recordsToSave: [attachmentRecord], recordIDsToDelete: [AnyObject]())
              operation.database = privateDatabase
              operation.atomic = false // Allow certain saves to fail and others succeed
              operation.modifyRecordsCompletionBlock = { (savedRecords: [AnyObject]!, deletedRecordIDs: [AnyObject]!, error: NSError?) in
                  if let error = error {
                      // Failed
                  } else {
                      // Success
                  }
              }
              operationQueue.addOperation(operation)
              
              //
              // Fetch By Record ID
              //
              
              privateDatabase.fetchRecordWithID(CKRecordID(recordName: "attachment1.jpg", zoneID: recordZoneID), completionHandler: { (record: CKRecord?, error: NSError?) -> Void in
                  // Record fetched successfully, so it definitely exists!
              })
              
              //
              // Query (Should return everything, but doesn't!)
              //
              
              private func fetchCloudAttachmentsFilenames(cursor: CKQueryCursor? = nil, previousFileNames: Set<String>? = nil, completion: (fileNames: Set<String>?, error: NSError?) -> Void) {
                  // Fetch names
                  var fileNames = previousFileNames ?? Set<String>()
                  let operation: CKQueryOperation
                  if let cursor = cursor {
                      operation = CKQueryOperation(cursor: cursor)
                  } else {
                      operation = CKQueryOperation(query: CKQuery(recordType: attachmentRecordType, predicate: NSPredicate(value: true)))
                      operation.zoneID = recordZoneID
                  }
                  operation.database = privateDatabase
                  operation.desiredKeys = [] // We only need recordID
                  operation.recordFetchedBlock = { (record: CKRecord!) -> Void in
                      fileNames.insert(record.recordID.recordName)
                  }
                  operation.queryCompletionBlock = { (cursor: CKQueryCursor?, error: NSError?) -> Void in
                      if let cursor = cursor where error == nil {
                          // More results
                          self.fetchCloudAttachmentsFilenames(cursor: cursor, previousFileNames: fileNames, completion: completion)
                      } else if let error = error where error.code != CKErrorCode.UnknownItem.rawValue {
                          // Error but ignoring unknown item type (it means no record type yet as there are no items)
                          completion(fileNames: nil, error: error)
                      } else {
                          // No more results so we have them all
                          // BUT "attachment1.jpg" DOES NOT EXIST
                          if !fileNames.contains("attachment1.jpg") {
                              // FAILED TO RETURN EXISTING RECORD
                          }
                          completion(fileNames: fileNames, error: nil)
                      }
                  }
                  operationQueue.addOperation(operation)
              }
              
            • Re: CloudKit record exists (added days ago), does not get returned by query but can be fetched by ID
              Samyro Level 1 Level 1 (0 points)

              I get exactly the same issue. Record doesn't appear in dashboard or fetching by query. But when I fetch by recordName, it exists.

              • Re: CloudKit record exists (added days ago), does not get returned by query but can be fetched by ID
                ramart Level 1 Level 1 (0 points)

                Same for me. The record doesn't appear in the dashboard or fetching by query although that the fields I'm querying by have the QUERYABLE indexes added, but when I fetch by recordName, it exists.