Best way to implement Enums with Core Data

What is the best way to bind Core Data entities to enum values so that I am able to assign a type property to the entity? In other words, I have an entity called Item with an itemType property that I want to be bound to an enum, what is the best way of going about this.


You'll have to create custom accessors if you want to restrict the values to an enum. So, first you'd declare an enum, like so:

typedef enum {
    kPaymentFrequencyOneOff = 0,
    kPaymentFrequencyYearly = 1,
    kPaymentFrequencyMonthly = 2,
    kPaymentFrequencyWeekly = 3
} PaymentFrequency;

Then, declare getters and setters for your property. It's a bad idea to override the existing ones, since the standard accessors expect an NSNumber object rather than a scalar type, and you'll run into trouble if anything in the bindings or KVO systems try and access your value.

- (PaymentFrequency)itemTypeRaw {
    return (PaymentFrequency)[[self itemType] intValue];
}

- (void)setItemTypeRaw:(PaymentFrequency)type {
    [self setItemType:[NSNumber numberWithInt:type]];
}

Finally, you should implement + keyPathsForValuesAffecting<Key> so you get KVO notifications for itemTypeRaw when itemType changes.

+ (NSSet *)keyPathsForValuesAffectingItemTypeRaw {
    return [NSSet setWithObject:@"itemType"];
}

You can do this way, way simpler:

typedef enum Types_e : int16_t {
    TypeA = 0,
    TypeB = 1,
} Types_t;

@property (nonatomic) Types_t itemType;

And in your model, set itemType to be a 16 bit number. All done. No additional code needed. Just put in your usual

@dynamic itemType;

If you're using Xcode to create your NSManagedObject subclass, make sure that the "use scalar properties for primitive data types" setting is checked.


An alternative approach I'm considering is not to declare an enum at all, but to instead declare the values as category methods on NSNumber.


If you're using mogenerator, have a look at this: https://github.com/rentzsch/mogenerator/wiki/Using-enums-as-types. You can have an Integer 16 attribute called itemType, with a attributeValueScalarType value of Item in the user info. Then, in the user info for your entity, set additionalHeaderFileName to the name of the header that the Item enum is defined in. When generating your header files, mogenerator will automatically make the property have the Item type.