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