Core Data and Computed Properties

Say you have a Core Data model, and you want to have some of the properties affect the others. It is possible to use computed properties to help to build these relationships. The best way to demonstrate this is via a real example.
Screen Shot 2016-08-01 at 00.07.06We are going to create an application that will store a list of people’s birthdays, as shown above.

Set Up The Project

To do this, create a new project called ‘Birthdays’.

  • Language set to ‘Swift’
  • Check ‘Create Document-Based Application’
  • Check ‘Use Core Data’

Screen Shot 2016-08-01 at 00.10.29

Set Up The Entity

  • Select ‘Document.xcdatamodeld’ in the Project Navigator and click ‘Add Entity’.
  • Create three attributes: age (Integer 16), dob (Date) and name (String)
  • Name your entity as ‘Person’

Screen Shot 2016-08-01 at 00.18.59

Create The User Interface

Select ‘Document.xib’ in the project navigator.

  • Delete the label placeholder in the centre.
  • Add a table view with three columns.
  • Set column headers to ‘Name’, ‘DOB’ and ‘Age’.
  • Delete the text field in the ‘DOB’ column, and replace it with a Date Picker.
  • Set the table view row height to fixed, with a value of 24
  • Add two push buttons, named ‘Add’ and ‘Remove’.
  • Add an array controller.

You should have something like this:
Screen Shot 2016-08-01 at 00.30.34

Set Up The Bindings

The Array Controller

Select the array controller and open the bindings tab.
Bind its ‘Managed Object Context’ to ‘File’s Owner’ and set the ‘Model Key Path’ to ‘self.managedObjectContext’.
Screen Shot 2016-08-01 at 00.32.56
Open the attributes inspector.
Set ‘Mode’ to ‘Entity Name’ and ‘Class’ to ‘Person’.
Check ‘Prepares Content’.

The Buttons

Control drag the Add button to the array controller, and select the ‘Add:’ method.
Control drag the Remove button to the array controller, selecting the ‘Remove:’ method.

The Table

Select the table view and bind its Content to the array controller.
Select the Name column’s ‘Table View Cell’ object, setting the ‘Behavior’ to ‘Editable’. Delete the value in the ‘Title’ box.
In the bindings tab, bind its value to ‘Table Cell View’ with a ‘Model Key Path’ value of ‘objectValue.name’
Select the Date Picker and bind its Value to the array controller, setting the ‘Model Key Path’ to ‘dob’.
Finally, select Age column’s ‘Table View Cell’ and bind its Value ‘Table Cell View’, setting the ‘Model Key Path’ to ‘objectValue.age’.

Now run your app. You should be able to add people to your list, and give them names and birthdays, but the age does not as yet update. In order to do this, we have to link the date from the date picker to the age value.

Setting Up the Computed Property

Select ‘Document.xcdatamodeld’. We need to add some further functionality to our entity. In order to do this, we need to edit the NSManagedObject’s subclass.
In the main menu, click ‘Editor > Create NSManagedObject Subclass…’
Click ‘next’, ‘next’ again, make sure that ‘Swift’ is selected as your language, then hit ‘Create’.
This creates two new files in your project, ‘Person+CoreDataProperties.swift’ and ‘Person.swift’. It is here that you will modify the entity.
Select ‘Person+CoreDataProperties.swift’.
Add the following function to convert an NSDate value into an age value:

func getAgeFromDate(date: NSDate) -> Int {
  let currentDate = NSDate()
  let calendar: NSCalendar = NSCalendar.currentCalendar()
  let ageComponents = calendar.components(.Year,
    fromDate: date,
    toDate: currentDate,
    options: [])
  let age = ageComponents.year
  return age
}

Now we are going to create a new variable to set the values of the NSManaged properties. Add the following property:

var dobValue: NSDate {
  get {
    if (self.dob == nil) {
      let defaultDate: NSDate = NSDate()
      self.age = self.getAgeFromDate(defaultDate)
      return defaultDate
    }
    else {
      return self.dob!
    }
  }
  set {
    self.dob = newValue
    self.age = self.getAgeFromDate(newValue)
  }
}

Finally, instead of binding the date picker directly to the ‘dob’ property, we are going to bind to the computed property instead, as this does the job of setting our ‘dob’ as well as our ‘age’ values in the entity.
Select the date picker, and for the value binding, set its ‘Model Key Path’ to ‘objectValue.dobValue’.
Screen Shot 2016-08-01 at 01.28.30
Now when you run the application, changing the date picker value updates the value in the age column.

So you have managed to create a birthday database app by typing less the 30 lines of code. Core data is so powerful when it comes to creating and managing data! I hope you found this tutorial to be useful. I found precious little information on customising entities with computed properties. Not too complicated when you know how!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s