Home > Software design >  CoreData can't save Object when non-Optional value is set in willSave()
CoreData can't save Object when non-Optional value is set in willSave()

Time:07-17

Context I have a non-Optional lastEditTS Attribute on an Entity, which I set every time the method willSave()gets called. However, this results in the following Saving error:

Error Domain=NSCocoaErrorDomain Code=1570 "lastEditTS is a required Value.\ ...


Code

public override func willSave() {
    lastEditTS = .now
    super.willSave()
}

Question:

  • How can lastEditTS be nil when saving the context?

Thanks a lot for your support!

CodePudding user response:

When setting properties in override methods like willSave etc you should use setPrimitiveValue instead. Setting properties directly will mark the object as dirty and make Core Data trying to save it again (and make another call to willSave).

setPrimitiveValue(Date.now, forKey: #keyPath(YourEntity.lastEditTS))

CodePudding user response:

Managed objects are validated before they're saved. Internally, Core Data validates your property values first and only saves if they're OK. In your case, since lastModified is nil when you try to save changes, validation fails. Your willSave function never gets called because validation already failed, so it has no effect.

You can override validation to make it work. It doesn't work quite like it seems at first-- you can't just set a value for lastModified. You need to modify the incoming value directly. Something like this:

@objc public func validateLastModified(_ value: AutoreleasingUnsafeMutablePointer<AnyObject?>) throws {
    if lastModified == nil {
        value.pointee = Date.now as AnyObject
    }
}

You don't call super here because validateLastModified doesn't exist there. You must check the value of lastModified and only change it if necessary, because Core Data will call validation again with your new value. If you change it every time you'll get stuck in an infinite validation loop.

  • Related