zrfrank
zrfrank

Reputation: 2698

What is the modern approach for Core Data Property Validation? Does Key-Value Validation still the de facto approach?

As the Core Data Programming Guide - Object Validation, updated to Swift 3, suggests that the Key-Value Validation utilizing the Key-Value Coding of objective-c runtime is the recommended approach to perform single property validation.

As the evolutions of Swift and iOS in recent years, does this approach still represent the best practice? And what are the practical caveats when applying this technic in modern iOS?

For example,

@objc(AuthorMO)
public class AuthorMO: NSManagedObject, Identifiable {
    @NSManaged public var uuid: UUID?
    @NSManaged public var name: String?
}

// MARK: Key-Value Property Validation
extension AuthorMO {
    @objc public func validateUuid(_ value: AutoreleasingUnsafeMutablePointer<AnyObject?>) throws {
        guard let newValue = value.pointee as? UUID else { return }
        // Custom property validation.
    }
    
    @objc public func validateName(_ value: AutoreleasingUnsafeMutablePointer<AnyObject?>) throws {
        guard let newValue = value.pointee as? String else { return }
        // Custom property validation.
    }
}

// MARK: LifeCycle Validation Alternative
// previously mainly used for inter-properties validation.
extension AuthorMO {
    public override func validateForInsert() throws {
        try super.validateForUpdate()
        try propertyValidations()
    }
    
    public override func validateForUpdate() throws {
        try super.validateForUpdate()
        try propertyValidations()
    }
    
    public func propertyValidations() throws {
        try validateUUID()
        try validateName()
    }
    
    public func validateUUID() throws {
        let newValue = primitiveValue(forKey: #keyPath(AuthorMO.uuid))
        // Custom property validation
    }
    
    public func validateName() throws {
        let newValue = primitiveValue(forKey: #keyPath(AuthorMO.name))
        // Custom property validation
    }
}

Upvotes: 1

Views: 317

Answers (2)

Tom Harrington
Tom Harrington

Reputation: 70966

This is one way of doing it. It's only automatically used when you're saving changes, and in that case all it can do is prevent saving and return an error message. You might display that error message to the user. If that fits your needs, then it's a good approach. You can also run it manually. It might be less useful in other situations, for example importing data from a server API. This is the only built-in technique specifically designed for property validation.

There are other ways-- literally any way that works for you to check that the property values fit your requirements. For example, you could write your own failable initializer, and have it return nil if any of the arguments are no good. Or have it throw so it can return an Error explaining why it can't initialize. Custom code like this won't prevent saving changes, but if you use it carefully it'll still make sure values match your requirements.

Upvotes: 1

Blazej SLEBODA
Blazej SLEBODA

Reputation: 9925

When working with CoreData this good way of validating a data. If you would like to work with SQLite using full potential of Swift then you should chose the GRDB project. This project is promoted by Swift Developers by means of dedicated sub forum on https://forums.swift.org forum site.

Upvotes: 0

Related Questions