使用核心数据进行数据验证:常见约束

无论应用程序使用哪种持久性框架,开发人员都将决定存储在应用程序的持久性存储中的内容。 这也意味着在将数据插入持久存储之前,开发人员负责验证数据。

如果您的应用程序使用Core Data保留数据,那么您很幸运。 该框架具有许多用于在将对象持久化到磁盘之前对其进行验证的API。 在本教程中,我将向您展示Core Data为开发人员提供了哪些用于验证对象的选项。

1.项目设置

最好的学习方法就是做事。 打开Xcode并基于Single View Application模板创建一个新项目。

项目设置

将项目命名为Validation并将Language设置为Swift 。 选中底部的使用核心数据 ,然后单击下一步

项目设置

2.填充数据模型

打开Validation.xcdatamodeld ,创建一个新实体,并将其命名为User。 将以下属性添加到用户实体:

  • 字符串类型的第一个
  • 字符串类型的最后一个
  • 字符串类型的电子邮件
  • 整数类型的年龄 16

创建另一个实体,将其命名为Note ,并将以下属性添加到该实体:

  • 字符串类型的标题
  • 字符串类型的内容
  • Date类型的createdAt

一个用户可以有多个注释,而一个注释只能属于一个用户。 这意味着我们需要以Note实体为目标,向User实体添加To To关系。 我们还需要将一个“一对一”关系添加到“ 注释”实体,并以“ 用户”实体为目标,并以“ 注释”为逆向关系。 这就是Xcode数据模型编辑器中的样子。

设置数据模型
设置数据模型

3.约束属性

可以在数据模型中定义公共约束。 让我告诉你这是如何工作的。 打开Validation.xcdatamodeld并选择用户实体。 选择电子邮件属性,然后打开右侧的数据模型检查器

数据模型检查器中的验证规则

在“ 验证”部分,您可以设置属性的最小和最大长度。 您甚至可以输入一个正则表达式,该属性的值必须匹配才能有效。 数据模型检查器还添加了设置默认值的功能,这对于必需的属性很方便。

这给我们带来了对属性的最明显的约束,即它们的可选性。 通过取消选中顶部的Optional复选框,您可以告诉Core Data该属性必须具有一个值才能使其有效。

如果对象未通过验证,则在执行保存操作时,Core Data会引发错误。 毋庸置疑,Core Data不允许将无效对象推送到应用程序的持久性存储中。

如果您选择User实体的age属性,您会注意到Validation部分看起来略有不同。 由于age属性的类型为Integer 16 ,因此可以为该属性设置最小值和最大值。 您也可以定义默认值。

数据模型检查器中的验证规则

选择Note实体的createdAt属性,然后打开Data Model Inspector 。 请注意,您可以指定最小和最大日期以及默认日期。

数据模型检查器中的验证规则

数据模型中定义的约束最重要的缺点是缺乏动态性。 例如,如果要将Date类型的属性约束为基于当前日期的值,则需要在代码中实现自定义验证。 我们稍后看一下它是如何工作的。

4.约束关系

关系与属性没有很大的不同。 它们也可能受到约束。 关系可以是可选的,也可以是必需的。 一对多关系的计数可以限制为最小值和最大值。 选择用户实体的notes属性,然后打开“ 数据模型检查器”音符关系的计数可以具有最小值和最大值。

数据模型检查器中的验证规则

能够向数据模型添加约束是一个强大的概念,很高兴知道它已内置在Core Data框架中。

5.验证对象

通过取消选中“ 数据模型检查器”中的“ 可选”复选框,选择“ 用户”实体并标记所需的每个属性。 选择age属性,并将最小值设置为0并将最大值设置为120 。 将属性的默认值设置为21

将约束添加到属性

打开AppDelegate.swift并更新application(_:didFinishLaunchingWithOptions:) ,如下所示。 我们创建User实体的实例并填充其属性。 请注意,我们将age属性设置为一个超出数据模型中指定的最大值的值。 我们可以通过调用validateForInsert()来询问托管对象对于插入持久存储是否有效。 由于此方法正在抛出,因此将其包装在do-catch语句中。

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    if let entity = NSEntityDescription.entityForName("User", inManagedObjectContext: self.managedObjectContext) {
        // Create Managed Object
        let user = NSManagedObject(entity: entity, insertIntoManagedObjectContext: self.managedObjectContext)

        // Populate Managed Object
        user.setValue(140, forKey: "age")
        user.setValue("Bart", forKey: "first")
        user.setValue("Jacobs", forKey: "last")
        user.setValue("me@icloud.com", forKey: "email")

        do {
            try user.validateForInsert()

        } catch {
            let validationError = error as NSError

            print(validationError)
        }

    }

    return true
}

如果您在模拟器或物理设备上运行该应用程序,则应该在控制台中看到以下错误。

Error Domain=NSCocoaErrorDomain Code=1610 "The operation couldn’t be completed. (Cocoa error 1610.)" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x7fef63611dd0> (entity: User; id: 0x7fef63613eb0 <x-coredata:///User/t8C45E95D-D8C3-4900-82FA-BC313D53D5882> ; data: {
    age = 140;
    email = "me@icloud.com";
    first = Bart;
    last = Jacobs;
    notes =     (
    );
}), NSValidationErrorValue=140, NSValidationErrorKey=age, NSLocalizedDescription=The operation couldn’t be completed. (Cocoa error 1610.)}

该错误非常清楚托管对象存在什么问题。 即使本地化描述有点模糊,错误也表明age属性的值不符合我们在数据模型中定义的约束。

验证期间可能会引发多个验证错误。 让我向您展示一下。 为避免迁移问题,请从模拟器中删除该应用程序。 重新访问数据模型并选择用户实体的最后一个属性。 打开右侧的数据模型检查器 ,然后取消选中“ 可选”以使该属性成为必需属性。

打开AppDelegate.swift并删除设置用户记录的姓氏的行。

user.setValue("Jacobs", forKey: "last")

再次运行该应用程序,然后检查以在控制台中输出。

Error Domain=NSCocoaErrorDomain Code=1560 "(null)" UserInfo={NSDetailedErrors=(
    "Error Domain=NSCocoaErrorDomain Code=1610 \"The operation couldn\U2019t be completed. (Cocoa error 1610.)\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x7feab8419690> (entity: User; id: 0x7feab84196f0 <x-coredata:///User/tD1D0A3BA-7F23-41A7-9567-5C1A30D6A0132> ; data: {\n    age = 140;\n    email = \"me@icloud.com\";\n    first = Bart;\n    last = nil;\n    notes =     (\n    );\n}), NSValidationErrorValue=140, NSValidationErrorKey=age, NSLocalizedDescription=The operation couldn\U2019t be completed. (Cocoa error 1610.)}",
    "Error Domain=NSCocoaErrorDomain Code=1570 \"The operation couldn\U2019t be completed. (Cocoa error 1570.)\" UserInfo={NSValidationErrorKey=last, NSLocalizedDescription=The operation couldn\U2019t be completed. (Cocoa error 1570.), NSValidationErrorObject=<NSManagedObject: 0x7feab8419690> (entity: User; id: 0x7feab84196f0 <x-coredata:///User/tD1D0A3BA-7F23-41A7-9567-5C1A30D6A0132> ; data: {\n    age = 140;\n    email = \"me@icloud.com\";\n    first = Bart;\n    last = nil;\n    notes =     (\n    );\n})}"
)}

错误对象的userInfo词典包含一个错误数组,这些错误通知我们在验证过程中出了什么问题。 请理解,如果您尝试保存未通过验证的托管对象,则会引发相同的错误。

结论

数据验证是数据持久性的关键方面。 您需要确保插入持久存储中的数据有效。 换句话说,您插入的数据需要符合您在数据模型和应用程序代码中定义的要求。

下周,我将向您展示如何在代码中创建更复杂的验证规则。 即使这种方法需要更多的工作,代码中的验证规则也更加灵活和强大。

翻译自: https://code.tutsplus.com/tutorials/data-validation-with-core-data-common-constraints--cms-26621

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值