4.3 数据验证错误
在把对象保存到持久化存储区之前,它们必须通过验证。假如某个对象未能通过验证,那么系统就会抛出domain为NSCocoaErrorDomain的NSError。验证错误(validation error)的类型一共有十几种,可以在Xcode里面跳转到NSManagedObject-ValidationError的定义以查看它们。跳转后的文件应该是CoreDataErrors.h,其中定义了如表4-1所示的这些验证错误。
表4-1 有可能出现的验证错误类型
目前的应用程序无法保存相关对象,因为一旦在上下文上面执行保存,程序就会失败,并给出错误码1600。我们刚才通过validateForDelete方法来防止程序执行不合乎Delete规则的保存操作,但是,在编写应用程序其他地方的代码时,开发者很容易就会忘了添加这种验证逻辑,从而导致程序出错,为此,我们需要添加一段“优雅的”错误提示代码,以作为最后的解决手段。这样的话,终端用户就可以把收到的错误码发送给开发者了。程序清单4-5中的这段代码用来引发验证错误。
程序清单4-5 AppDelegate.m文件中的demo方法(试图删除unit对象)
请按下列步骤修改Grocery Dude,使应用程序再度于保存上下文时出错:
1.修改AppDelegate.m文件中的demo方法,用程序清单4-5替换原有代码。
2.再次运行应用程序,这次应该会在保存的时候失败,并产生1600错误。
为了向用户显示验证错误,我们新编写了名为showValidationError的方法,用它拦截验证错误,并给出适当的警告信息。新方法必须根据1600这个错误码查出更为详细的信息,然后才能继续往下执行。根据表4-1可知,1600这个错误码意味着发生了NSValidationRelationshipDeniedDeleteError。程序清单4-6中的这个show-ValidationError方法可以捕获并向用户展示这种错误。
程序清单4-6 CoreDataHelper.m文件中的showValidationError方法
showValidationError方法首先剖析NSError的详细内容,然后把每个错误都分别放在errors数组里。假如这个数组不是空的,那么该方法就迭代它,并在这个过程中构建出表示错误信息的字符串。创建好字符串之后,把它传给UIAlertView,以便展示给用户。
请按下列步骤修改Grocery Dude,以便向用户弹出与验证错误有关的警示信息:
1.把程序清单4-6中的代码添加到Core-DataHelper.m文件底部,并放在@end前面。
2.修改CoreDataHelper.m文件中的saveContext方法,将[self showVali-dationError:error];添加到Failed to save这一行的下边。
3.运行应用程序。这次将会看到如图4-9所示的画面。
图4-9 与直接令程序崩溃相比,通过警示视图来显示错误信息是一种对用户比较友好的方式
从现在开始,如果程序在保存上下文的时候因为数据验证问题而失败,那么用户至少会看到一个优雅的错误信息提示界面。我们很容易就能像程序清单4-7这样,把与其他类型的验证错误相关的描述信息添加到showValidationError方法里。
程序清单4-7 CoreDataHelper.m文件中的showValidationError方法(又添加了一些case分支)
请按下列步骤修改Grocery Dude,以便增强错误信息提示界面对验证错误的描述能力:
1.修改CoreDataHelper.m文件中的showValidationErrors方法,把程序清单4-7中的case分支添加到default这一行的上方。
2.把AppDelegate.m文件demo方法中的所有代码都删掉。
3.再度运行应用程序,这次应该不会再显示有关验证错误的信息提示界面了。