Search code examples
ioscore-datamogenerator

How to use type-safe struct type Core Data attributes with mogenerator?


For attributes of struct types that NSKeyValueCoding can handle, I use the Core Data accessor pattern described in Apple's docs here.

For example, an NSRange struct can be specified in the Core Data model as of type Transformable, then the NSValue rigmarole can be avoided for clients by providing accessors in an NSManagedObject subclass of the form:

Interface:

@property(assign, nonatomic) NSRange range;

Implementation;

- (NSRange) range {

    [self willAccessValueForKey:@"range"];
    NSRange retVal = range;
    [self didAccessValueForKey:@"range"];

    return retVal;
}

- (void)setRange:(NSRange)aRange {

    [self willChangeValueForKey:@"range"];
    range = aRange;
    [self didChangeValueForKey:@"range"];
}

Mogenerator's generated NSManagedObject subclasses, however, declare Transformable attributes as NSObject properties, so clients need to get/set NSValues.

What's the best way to handle this situation with mogenerator, whilst (1) keeping with the simple Transformable pattern rather than messing with transient backing attributes, and (2) avoiding any edits of Mogenerator's 'machine' classes?


Solution

  • The ultimate way to deal with this would be, as scc suggested in the previously accepted answer, to change the mogenerator template files. They would need to (a) change the transformable attribute's accessor to be of the appropriate type (NSRange in this instance) and then (b) add the accessors with the appropriate KVO method calls.

    As that's more than I have time right now to figure out how to do, my temporary expedient is as follows:

    • add an attributeValueClassName key to the attribute's userInfo dict (in the Core Data editor), with the value NSValue (just to make sure the generator's accessors will be NSValue rather than NSObject).
    • in the human-editable mogenerator output, add accessors like those in the question, except with a new name (eg. rangeValue and setRangeValue). The underlying values will still be the persisted NSValues, but my accessors take care of the KVO and boxing/unboxing.

    Not ideal, but I do get strongly-typed accessors without having to edit the mogenerator machine files.