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.