paulw11 / Seam3

Cloudkit based persistent store for Core Data
Other
209 stars 25 forks source link

Setting reference to nil does not remove reference from CloudKit #52

Closed bvelasquez closed 7 years ago

bvelasquez commented 7 years ago

I have a simple relationship 1 to Many. Entry has a relationship to 1 Event, and the inverse Event relationship "entries" may have many Entry's. The event relationship is optional, and may have an event or may not. When I nil the event relationship for an Entry, the CloudKit relationship does not get removed.

What is the proper way of removing a relationship so that Seam3 will synchronize appropriated to CloudKit?

Edit:

The CoreData object graph is updating appropriately. The reference between the Entry and the Event does get removed. However, next time I open the App, CloudKit sync's the relationship back into Core Data and the relationship comes back. Any help is appreciated.

bvelasquez commented 7 years ago

I changed the code below in NSManagedObject+CKRecord.swift to set the CKRecord object for key "entity_name" to nil if there is no managed object. Not sure if this is the correct solution, or there is more at work that I don't understand.

fileprivate func setRelationshipValues(ofCKRecord ckRecord:CKRecord, withValuesOfRelationshipWithKeys keys: [String]?) {
    var relationships: [String] = [String]()
        if keys != nil {
            relationships = keys!
        } else {
            relationships = Array(self.entity.toOneRelationshipsByName().keys)
        }
        for relationship in relationships {
            if let relationshipManagedObject = self.value(forKey: relationship) as? NSManagedObject {
                let recordIDString: String = relationshipManagedObject.value(forKey: SMStore.SMLocalStoreRecordIDAttributeName) as! String
                let ckRecordZoneID: CKRecordZoneID = CKRecordZoneID.smCloudStoreCustomZoneID()
                let ckRecordID: CKRecordID = CKRecordID(recordName: recordIDString, zoneID: ckRecordZoneID)
                let ckReference: CKReference = CKReference(recordID: ckRecordID, action: CKReferenceAction.deleteSelf)
                ckRecord.setObject(ckReference, forKey: relationship)
            }
            **else {
                ckRecord.setObject(nil, forKey: relationship)
            }**
        }
    }