Group Group Group Group Group Group Group Group Group

raywenderlich.com Forums

Video Tutorial: Intermediate Core Data Part 2: Advanced Attributes

Explore some advanced topics regarding Core Data model attributes including validation, constraints, fetched properties, and transformable types.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/3815-intermediate-core-data/lessons/3

Hi Greg,

Thanks for the video!

This is a question similar to one that has been asked before by bjmiller22:

have you tried to make a computed property on the Device NSMO subclass for purchasedOnSameDate : [Device] just as a safer way to get the valueForKey("purchasedOnSameDate") as? [Device] array? I thought it would be great to have it just like any other property on the class, but it crashes every time it is accessed. Even adding it inside if let binding still crashes, and no useful output in the console is given

According to your reply, I understand that this can be achieved if I name this property different from the fetched property’s name. But I do not understand why I could not access the fetched property directly, as you said there is already one on the object? Such as:

device.purchasedOnSameDate

I thought this would return an array of values, but xcode complains that there is no such property (I have tried to update the subclass). My guess is since this is a computational property, it is created on the fly during run time?

Thank you so much! The course is really helpful for me to understand core data!

I changed my mind. The problem was caused by my own typo error.

When you add the try/catch to catch the validation error, in the catch you assume the error is a validation error and put up a message without further testing this. I think that is a bad programming habit, you should always be sure what you’re in a catch for and provide program flow for that.

Also, you do show the concept of (field/value) validation but not constraints (such as uniqueness) even though the description of the video states ‘constraints’.

Great tutorial!

Could you please in addition provide a working example on how to change an attributes type by applying a custom migration policy? I have an annual subscription at raywenderlich.com and also bought the book “Core Data by Tutorials”. However, I could not find a solution to my problem yet.

In my particular case I have an entity called Location with the common attributes latitude and longitude. In version 1 of my data model both attributes are of type String. In version 2 I have changed the type to Double.

Next I have created a mapping model including the entity mapping LocationToLocation. In the respective value expressions I’ve added FUNCTION($entityPolicy, "stringToDoubleWithString:" , $source.latitude). As custom policy I have added MyApp.LocationToLocationMigrationPolicy1to2 to the mapping model.

The corresponding custom migration policy file looks like this:

import Foundation
import CoreData

class LocationToLocationMigrationPolicy1to2: NSEntityMigrationPolicy {
    func stringToDouble(value: String?) -> Double {
        return Double(value ?? "") ?? 0.0
    }
}

However, when running my app I am getting the following error message:

MyApp.sqlite options:{
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1; } … returned error Error Domain=NSCocoaErrorDomain Code=134140 “(null)”
[…]
Error Domain=NSCocoaErrorDomain Code=134190 “(null)”
UserInfo={entity=Location, property=altitude, reason=Source and
destination attribute types are incompatible}]

I spend already few hours in searching for solutions at stack overflow and on the internet.

Thanks for your advice in advance!