Mastering In CoreData (Part 8 Validation In Core Data)

Core Data

Core Data, allows you to put validation logic into the Managed Object Model and specify most common constraints as opposed to writing validation logic in your code. Before dump data into the Persistent Store, you can apply validation on objects. If the objects follow the constraint context data will persistent successfully else it will throw an error. It’s a developer responsibility to add constraint. The framework has a number of APIs for validating objects before they are persisted to disk. In this tutorial, I will show you what options Core Data offers for developers for validating objects. In part 2 we wrote this point

Managed Object Context (MOC)

It provides Caching, Change tracking, Lazy loading, Redo, Undo and validation features

How Validation Works in Core Data

The validation constraints are applied by Core Data only during a save operation or upon request. (you can invoke the validation methods directly at any time it makes sense for your application flow)

Getting Started

You can Download the starter project here. This project is the continuation of the tutorials see Part 5 and Part 7 where we created this project.

If you are following previous tutorials delete the application first before start doing anything

Validation on Properties

Go to CrudOperationCoreData.xcdatamodeld → Tap on User Entity → Double Tap on firstName attribute → On the right hand side Model inspector add validation. We added two validation min and max length of the firstName also we added default value as shown in Figure 1. Make sure max and min Length checkbox is checked.

Figure 1

Let’s dive into the code and check if validation is working or not. As you see when we create User Entity default value was assigned to the firstName property and when we updated firstName value with more than 12 characters , it updated successfully on context which is in memory but when we try to commit changes to the persistent store it checks the validation first and if it fails it will throw an error as seen in Figure 2.

You can request validation before calling save method throw validateForInsert(), validateForUpdate() instance method on Entity itself and you can override this method to apply custom validation with your code.
We will look custom validation in the last section of this part

Figure 2

Validation on Date

You can apply min and max validation on Date as well as shown in Figure 3.
Make sure min and max Date checkbox should checked otherwise validation will not work.

Figure 3

Validation on Relationships

Relationships are not very different from attributes. They too can be constrained. A relationship can be optional or required. The count of a To Many relationship can be constrained to a minimum and a maximum value.

Go to CrudOperationCoreData.xcdatamodeld →Tap on User Entity →Tap on tasks relationship attribute → On The Model inspector add Min and Max validation as shown in Figure 4

Figure 4

Delete the application first and add three tasks on User object as shown in Figure 5

Figure 5

When we try to save it. It will throw an error as shown in Figure 6 since we added max tasks object for a single User object limit which is two and we are adding three. It added three tasks successfully on context which is in memory but when we try to commit changes (using save() method) to the persistent store it checks the validation first and if it fails it will throw an error as seen in Figure 6.

You can request validation before calling save method throw validateForInsert(), validateForUpdate() instance method on Entity itself and you can override this method to apply custom validation with your code.
We will look custom validation in the last section of this part

Figure 6

Regex Validation

Now we will explore how to add regex in Model inspector core data. We will apply regex on user firstName property that will allow at least one character and the character will be of lowercase (^[a-z]{1,}$) alphabet as shown in Figure 7.

Figure 7

When we try to save the object with uppercase letter it will throw an error as shown in Figure 8.

Figure 8

Custom Property Level Validation

NSManagedObject provides consistent hooks for implementing property (and interproperty) values. So in this section we will first do coding part than theory because it’s theory is complicated . In previous section we applied constraint using Managed object model inspector features .

Apply Constraint Using Code

In this coding part we will apply min and max length constraint using code. First delete the application and removed older constraint we applied in previous section from core data model file.

Choose New → File… from Xcode’s File menu and select the Swift file → “User+CoreDataValidations” → create

For custom validation we need to override validateValue method. The input value is a pointer to an object reference (an id *). This means that in principle you can change the input value. However, doing so is strongly discouraged because there are potentially serious issues with memory management.

This is different in previous swift versions so it might not work for older projects see documentation for that. As you can see in the Figure 9 it is checking user secondName property and it will throw an error if it is nil, empty or exceed limit of 12 characters

Figure 9

Now add User with secondName property with max 12 count limit and see whether it is showing custom error or not we just created and as you can see in the Figure 10 it is showing custom error “The User Second name cannot be greater than 12 character”.

Figure 10

Implementing Custom Interproperty Validation

It is possible for the values of all the individual attributes of an object to be valid and yet for the combination of values to be invalid. For example insert or save object to persistent store if user firstName and secondName both should not exceed 12 characters limits

NSManagedObject provides additional opportunities for validation — update, insertion, and deletion — through the validateFor… methods such as validateForUpdate:. If you implement custom interproperty validation methods, you call the superclass’s implementation first to ensure that individual property validation methods are also invoked. If the superclass’s implementation fails (that is, if there is an invalid attribute value), you can do one of the following:

  • Return NO and the error created by the superclass’s implementation.
  • Continue to perform validation, looking for inconsistent combinations of values.

As you can see in below Figure 11 and 12 we did no of things

  1. On User secondName property we add value with less than 12 characters
  2. On firstName property we exceeded limit of 12 characters
  3. When we called save() method it first call validatevalue for each property custom cvalidation since we only cater secondName property it will validate secondName and pass it.
  4. After that overridden method validateForInsert() will call to check the interproperty Validation and it will throw custom error that we just created since firstName didn’t match the validation
Figure 11
Figure 12

Summary

In this part 8 we looked how to validate objects using Core data features. We first looked the build in validation and then we looked some custom validation as well.

What Next?

In the next part we will look NSFetchRequest in depth with coding and diagrams.

Useful Links

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/ObjectValidation.html

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

https://code.tutsplus.com/tutorials/data-validation-with-core-data-advanced-constraints--cms-26623

Senior iOS Engineer | HungerStation | Delivery Hero