I have a two simple Record Types: Artwork and Artist. Artwork as a child may belong to one Artist, however one Artist may have multiply artworks.
Below are the screenshots related to mentioned Record Types.

I can simply setup artist for artwork the following way:
let artistID = CKRecordID(recordName: "F297D690-888B-4B55-9FBD-27CAEF4BBD83")
let artworkID = CKRecordID(recordName: self.idTextField.text!)
self.container.publicCloudDatabase.fetchRecordWithID(artworkID, completionHandler: { artwork, error in
if let artwork = artwork {
artwork["artist"] = CKReference(recordID: artistID, action: CKReferenceAction.None)
self.container.publicCloudDatabase.saveRecord(artwork, completionHandler: { artwork, error in
print("done")
})
}
})
But the question is:
How to setup relationships in reversed relation? In other words how to add artworkID to the reference list of artistID?
Apple says:
...to represent the one-to-many relationship from
ArtisttoCollectionin the object model, add a reference field to theCollectionrecord.
But how to do this?
This is the simplest answer I have found:
let artworkID = CKRecordID(recordName: self.idTextField.text!)
if let artist = artist, var artworks = artist["artworks"] as? [CKReference] {
let reference = CKReference(recordID: artworkID, action: CKReferenceAction.None)
if !artworks.contains(reference) {
artworks.append(reference)
}
artist["artworks"] = artworks
//here you can save your changes or do whatever it needs
}
The key to your problems can be found in the Apple documentation that says...
https://developer.apple.com/library/ios/documentation/CloudKit/Reference/CKReference_class/
It is permissible to create circular owning references for a set of records.
To save multiple records containing references between them, save the target records first or save all the records in one operation using the same CKModifyRecordsOperation object.
The code to setup a reference in CloudKit I sure you seen?
let uniqReference = NSUUID().UUIDString
let unqUUID = CKRecordID(recordName: uniqUUID)
let newRecord = CKRecord(recordType: "Blah", recordID: uniqUUID)
It says you need to save all your records @ the same time with a CKModifyOperation.
func saveLeCollection(theGlob:NSURL) {
let container = CKContainer(identifier: "Blah.com")
let publicDB = container.publicCloudDatabase
let uniqUUID = CKRecordID(recordName: uniqReference)
let newRecord = CKRecord(recordType: "Blah", recordID: uniqUUID)
let whistleAsset = CKAsset(fileURL: theImage)
newRecord["theImage"] = whistleAsset
newRecord.setObject(uniqUUID, forKey: "theLink")
var localChanges:[CKRecord] = []
localChanges.append(newRecord)
let saveRecordsOperation = CKModifyRecordsOperation(recordsToSave: localChanges, recordIDsToDelete: records2Erase)
saveRecordsOperation.savePolicy = .ChangedKeys
saveRecordsOperation.perRecordCompletionBlock = { record, error in
if error != nil {
dispatch_async(dispatch_get_main_queue()) {
self.showAlert(message: error!.localizedDescription)
print(error!.localizedDescription)
}
}
// deal with conflicts
// set completionHandler of wrapper operation if it's the case
}
saveRecordsOperation.modifyRecordsCompletionBlock = { savedRecords, deletedRecordIDs, error in
if error != nil {
dispatch_async(dispatch_get_main_queue()) {
self.showAlert(message: error!.localizedDescription)
print(error!.localizedDescription)
}
} else {
// deal with conflictsay
// set completionHandler of wrapper operation if it's the case
}
}
}
saveRecordsOperation.qualityOfService = .Background
publicDB.addOperation(saveRecordsOperation)
}
If I store the ArtistID in my artwork record, the same ID in every artwork record I have a many->one reference. And with my reference List I have one->many reference with my Artist record pointing to each artwork record.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With