Jon
Jon

Reputation: 4732

Can I use a custom initializer for a core data model object?

I use Core Data and have an object ExerciseForRoutine. I'm currently manually creating it and then settings it's attributes, which seems to waste code. Is there any way I can create a custom init method to handle this in one line (I know how to do around alloc/init, but core data has a different init method..)

Current Code:

ExerciseForRoutine *exerciseForRoutine = (ExerciseForRoutine *)[NSEntityDescription insertNewObjectForEntityForName:@"ExerciseForRoutine" inManagedObjectContext:managedObjectContext];
exerciseForRoutine.name = self.selectedExercise;
exerciseForRoutine.timeStamp = date;
exerciseForRoutine.muscleGroup = self.muscleName;
exerciseForRoutine.musclePicture = self.muscleURL;

ExerciseForRoutine Class

@class Routine;

@interface ExerciseForRoutine : NSManagedObject {
@private
}
@property (nonatomic, strong) NSDate * timeStamp;
@property (nonatomic, strong) NSString * name;
@property (nonatomic, strong) NSString * muscleGroup;
@property (nonatomic, strong) NSString * musclePicture;
@property (nonatomic, strong) Routine * exerciseToRoutine;

@end

@implementation ExerciseForRoutine
@dynamic timeStamp;
@dynamic name;
@dynamic muscleGroup;
@dynamic musclePicture;
@dynamic exerciseToRoutine;

Upvotes: 2

Views: 2553

Answers (3)

AtomicBoolean
AtomicBoolean

Reputation: 1210

I did this using awakeFromInsert and awakeFromFetch.

From Apple's documentation:

In a typical Cocoa class, you usually override the designated initializer (often the init method). In a subclass of NSManagedObject, there are three different ways you can customize initialization —by overriding initWithEntity:insertIntoManagedObjectContext:, awakeFromInsert, or awakeFromFetch. You should not override init. You are discouraged from overriding initWithEntity:insertIntoManagedObjectContext: as state changes made in this method may not be properly integrated with undo and redo.

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/Articles/cdManagedObjects.html

Upvotes: 1

fatuhoku
fatuhoku

Reputation: 4911

To add to @Radix's answer, you should consider using mogenerator because it'll do much of that subclassing business for you.

http://rentzsch.github.io/mogenerator/

See here for a guide to set it up and have it running on XCode 5.

There's a small caveat to watch out for though: if you get an assertion failure that reads:

-[MOGeneratorApp setModel:] blah blah blah

Then you should point mogenerator to the .xcdatamodel file inside of the .xcdatamodeld package in your Run Script Phase, like so:

mogenerator -m Model.xcdatamodeld/Model.xcdatamodel -O Project/Model --template-var arc=true

Where Project is the name of your project and Model is the name of your model.

See https://github.com/rentzsch/mogenerator/issues/169.

Upvotes: 0

Radix
Radix

Reputation: 3657

The classes which Xcode creates for handling core data objects should not be overridden, instead what you could do is create your own custom class which inherits from NSObject and write your methods to handle the managed object their.

Sol: You can do this with the help of the parameterized init method

Then it would look something like this

CoreDataHelperClass *someobj = [[CoreDataHelperClass alloc]initWithname:@"name" andTimeStamp:@"Time" andMuscleGroup:@"musclegroup" andPicture:UIImagePNGRepresentation(someimageObj)];

To do the above you need to add your own init method in the CoreDataHelperClass class like this

.h part of CoreDataHelperClass


- (id)initWithName:(NSString*)name andTimeStamp:(NSString*)timeStamp andMuscleGroup:(NSString*)group andPicture:(NSData*)imageData;

.m part of CoreDataHelperClass


- (id)initWithName:(NSString*)name andTimeStamp:(NSString*)timeStamp andMuscleGroup:(NSString*)group andPicture:(NSData*)imageData
{

//you assignment code to the core data attributes goes here

ExerciseForRoutine *obj = [[ExerciseForRoutine alloc]init];

obj.name = name;
obj.timestamp = timeStamp;

//and so on

return self;

}


Anyways what you could also do is pass a dictionary with the keyvalue pair get the values in your custom class or you may also pass an NSMutableArray like what ever suits your business model both will work.

You can get the values of Dictionary or Array inside your CoreDataHelperClass and assign those values to your attribute.

Hope i have got your query right if not then kindly mention the error part via comments

Upvotes: 0

Related Questions