【问题标题】:What is the modern approach for Core Data Property Validation? Does Key-Value Validation still the de facto approach?核心数据属性验证的现代方法是什么?键值验证仍然是事实上的方法吗?
【发布时间】:2021-01-29 09:29:28
【问题描述】:

Core Data Programming Guide - Object Validation 更新到 Swift 3,建议使用 Objective-c 运行时的键值编码的键值验证是执行单个属性验证的推荐方法。

随着近年来 Swift 和 iOS 的演进,这种方法是否仍然代表最佳实践?在现代 iOS 中应用该技术时有哪些实际注意事项?

例如,

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

【问题讨论】:

    标签: ios swift core-data


    【解决方案1】:

    这是一种方法。它仅在您保存更改时自动使用,在这种情况下,它所能做的就是阻止保存并返回错误消息。您可能会向用户显示该错误消息。如果这符合您的需求,那么这是一个好方法。您也可以手动运行它。在其他情况下它可能不太有用,例如从服务器 API 导入数据。这是唯一专为属性验证而设计的内置技术。

    还有其他方法——实际上是任何可以让您检查属性值是否符合您的要求的方法。例如,您可以编写自己的可失败初始化程序,并在任何参数无效时让它返回nil。或者让它throw,这样它就可以返回一个Error,解释它为什么不能初始化。像这样的自定义代码不会阻止保存更改,但如果您小心使用它,它仍然可以确保值符合您的要求。

    【讨论】:

      【解决方案2】:

      使用 CoreData 时,这是一种验证数据的好方法。如果您想使用 Swift 的全部潜力使用 SQLite,那么您应该选择 GRDB 项目。本项目由 Swift Developers 通过https://forums.swift.org 论坛网站的专门子论坛进行推广。

      【讨论】:

      • 感谢您的回答。 GRDB 非常有前途,我确实计划在未来的项目中使用它。尽管在当前的项目中,我大量使用 Core Data 来利用其与 CloudKit 的集成同步。使用 GRDB 实现自定义 cloudkit 同步将需要大量工作。
      • @zrfrank CoreData 是一个非常好的框架。
      • 确实是最实用的解决方案。虽然由于它的 OC 特性,并且在现代持久历史跟踪、查询生成和 cloudkit 之前已经实践了很多滴答声,但更不用说现在的 UI 几乎是反应式 rx/combine。使用一些旧技术时我不是很自信。
      • Apple 没有将 Combine 集成到 CoreData 中,所以开发者必须自己做。 RxSwift 有一个 CoreData 扩展。如果你喜欢使用 Combine/RxSwift,并且你有复杂的查询依赖于其他查询,那么使用 Combine 或 RxSwift 会很有帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-01
      • 2020-02-11
      相关资源
      最近更新 更多