编辑:我想让大家都知道,自从我发布这个月以来,我一直在努力解决这个问题.现在有一个 repo on github,它显示了如何轻松实现这一目标并保持与KVC的兼容性.没有理由在iOS上避免核心数据验证.它可能与Mac OS X不同,但它并不困难或困难.

我在视图控制器中编辑Person对象的属性. Person是NSManagedobject子类.我正在使用Core Data进行早期(保存前)验证.我正在使用记录的validateValue:forKey:error:这样的方法……

NSError *error;
BOOL isValid = [person validateValue:&firstNameString forKey:@"firstName" error:&error];
if (!isValid) {
    ...
}

我在Xcode的Core Data模型编辑器中设置了最小值和最大值.当我验证firstName并且它太短时我得到这样的错误……

Error Domain=NSCocoaErrorDomain Code=1670 "The operation Couldn’t be completed. (Cocoa error 1670.)" UserInfo=0x8f44a90 {NSValidationErrorObject=<Event: 0xcb41a60> (entity: Event; id: 0xcb40d70 <x-coredata://ADB90708-BAD9-47D8-B722-E3B368598E94/Event/p1> ; data: {
firstName = B;
}),NSValidationErrorKey=firstName,NSLocalizedDescription=The operation Couldn’t be completed. (Cocoa error 1670.),NSValidationErrorValue=B}

但是我没有任何东西可以显示给用户.但错误代码在那里,所以我可以做这样的事情……

switch ([error code]) {

        case NSValidationStringTooShortError:
            errorMsg = @"First name must be at least two characters.";
            break;

        case NSValidationStringTooLongError:
            errorMsg = @"First name is too long.";
            break;

    // of course,for real,these would be localized strings,not just hardcoded like this
    }

这在概念上是好的,但firstName和其他Person属性在其他视图控制器上是可编辑的,因此必须在任何视图控制器上编辑firstName时再次实现切换.肯定有更好的办法.

查看属性级验证的核心数据文档揭示了这一点……

If you want to implement logic in addition to the constraints 
you provide in the managed object model,you should not override 
validateValue:forKey:error:. Instead you should implement methods 
of the form validate<Key>:error:.

所以我在Person.m中实现了validateFirstName:error:并且方便地,它通过视图控制器中的现有validateValue:forKey:error:方法执行,就像文档所说的那样.

但是在validateFirstName:error:中,即使firstName太短,错误仍然是nil.当我继续并控制返回到视图控制器时,会出现类似于此问题顶部的错误,但同样,这已经太晚了.我希望在控制时间到达validateFirstName:error:时,firstName将根据模型编辑器中指定的约束进行验证,并且填充的错误对象将通过error参数传入.但事实并非如此.

我留下了两个想法,可能会为转换声明带来一个好的家园……

>在Person.m中实现一个自定义方法,如firstNameValidationForValue:error:.视图控制器将调用该方法.在firstNameValidationForValue中:error:call validateValue:forKey:error:.当它返回错误时,构造一个有意义的错误消息,使用该开关,创建一个新的NSError对象并将其返回给视图控制器以供使用.这有效,但它偏离了标准的KVC方法.
>从Xcode中的Core Data模型编辑器中删除所有验证,并执行validateFirstName:error:等方法中的所有验证.根据结果​​,创建一个新的NSError对象并将其返回给视图控制器以供使用.这具有约束和错误消息在相同方法中的优点.而且,与第一个想法不同,继续遵循标准的KVC方法.

你会怎么做?还有另外一种方法吗?

编辑:编辑周期的其他详细信息……

编辑周期从用户点击添加开始.一个新的Person对象被插入到MOC中.视图显示用于编辑的表单,导航栏上显示“取消”和“完成”按钮.用户开始在fieldA中输入数据,完成并点击fieldB.假设fieldA必须在继续之前有效.在fieldB成为第一个响应者之前,fieldA的验证运行.它失败.视图控制器显示从验证返回的错误消息,而fieldA仍然是第一个响应者.用户修复了问题,然后再次点击fieldB.再次验证运行,这次它通过. fieldB成为第一个响应者.这个“添加数据/点击另一个字段或点击下一个/验证/移动到下一个字段与否”过程继续.

重要的是要知道用户可以随时点击取消.在这种情况下,就MOC而言,我所要做的就是[myMOC rollback] ;.

@ImHuntingWabbits:如果我调用save而不是validateValue:forKey:error:该方法存在问题.假设用户在fieldA中输入数据.用户点击fieldB并运行fieldA的验证.此验证使用“保存然后解析错误”方法.但假设它通过,所有其他领域也通过.所以现在MOC已经被保存了.但是用户没有点击Done并且可以很好地按下取消.如果用户点击取消,则必须撤消保存.如果模型非常简单但可能非常复杂,那可能相对容易.在我的特殊情况下,我不想采取这种方法.

另一个编辑

我们是否可以在github上重新召集:github.com/murraysagal/CoreDataValidationWithiOS我在那里有一个示例应用程序,也许更好地描述了自述文件中的问题.示例应用程序显示,验证通常在iOS上并不困难.该应用程序演示了如何将有意义的错误消息发送回VC并保持完全符合KVC标准.

它讨论了核心数据的两种可能的增强功能,在将它们放到雷达之前,我想要一些反馈.

解决方法

我不会在iOS上使用核心数据验证.核心数据验证是为带有绑定的桌面设计的,而不是针对iOS设计的.

您可以更轻松地在视图控制器中进行验证,并使用核心数据验证作为备份,而不是尝试将核心数据验证连接到用户界面.

更新

Could you explain why you think it will be easier to implement validation on the View Controller level. While proper validation and error handling is never easy,I can’t see a reason why the Core Data level validation should be more complex (besides the issue that validations are possibly performed more than one time,even when it is not required). You also don’t answer the case where there is no VC,or when there are more than one VCs handling objects. Also,certain validations can’t be performed on VC level (e.g. check for uniqueness of certain properties,which is a pain anyway).

当Core Data与用户界面之间存在相当紧密的耦合时,为OS X添加了核心数据验证.这种耦合被称为绑定.使用绑定,立即进入文本字段并“自动”添加到与该字段关联的核心数据实体.

此外,当该数据更新时,Core Data可以“回复”验证回到文本字段,以便文本字段可以拒绝数据输入并解释它被拒绝的原因.

这些绑定在iOS上不存在.它们需要手动编写每个数据入口点.

既然我们正在编写这些检查点,那么当我们可以直接将更集中的验证编写到视图控制器中并保存自己的抽象级别时,没有理由尝试挂钩像Core Data的验证这样的通用系统.

在数据导入的情况下,我们再次有一个处理导入的控制器.导入控制器和核心数据之间没有直接连线,所以当我们编写专注的代码来解决问题时,我们还有理由尝试插入像Core Data验证这样的通用系统.

通用系统泄漏边缘情况.如果有人花时间来覆盖大多数边缘情况(如Core Data和OS X上的绑定),那么继续使用它们.但是,如果你必须自己覆盖这些边缘或连接代码,那么集成到通用系统中的价值就很小.对于通用系统不是为处理用例而设计的情况尤其如此(例如核心数据验证和iOS).

Core Data的几个部分早于iOS,并且不适合iOS.验证就是其中之一.

ios – 如何通过核心数据验证将有意义的错误消息反馈给视图控制器?的更多相关文章

  1. HTML5 播放 RTSP 视频的实例代码

    目前大多数网络摄像头都是通过 RTSP 协议传输视频流的,但是 HTML 并不标准支持 RTSP 流。本文重点给大家介绍HTML5 播放 RTSP 视频的实例代码,需要的朋友参考下吧

  2. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. 详解如何通过H5(浏览器/WebView/其他)唤起本地app

    这篇文章主要介绍了详解如何通过H5(浏览器/WebView/其他)唤起本地app的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. H5混合开发app如何升级的方法

    本篇文章主要介绍了H5混合开发app如何升级的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. AmazeUI 折叠面板的实现代码

    这篇文章主要介绍了AmazeUI 折叠面板的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码

    这篇文章主要介绍了HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  7. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  8. html5唤起app的方法

    这篇文章主要介绍了html5唤起app的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. HTML5拍照和摄像机功能实战详解

    这篇文章主要介绍了HTML5拍照和摄像机功能实战详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部