GetMe4GetMe
GetMe4GetMe

Reputation: 927

iOS, Core Data is adding new object to wrong entity every time when i save context?

DataModel

i new to core data. here i am trying to save bunch of Statement in one Month.But i dont know how to insert object in core data with relationship. what my code is doing, it saving month in Month entity and statements in Statement entity without any relationship. every time i save it create new object in Month entity. my DataModel has One to Many Relationships. for example current (month) November than i want to insert few statement related to November. than next month December i want to insert few statement related to December. thats what i am trying to achieve. sorry for bad my english.
`

NSManagedObjectContext *context = [self managedObjectContext];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Month" inManagedObjectContext:context];
Month *month = [[Month alloc] initWithEntity:entity insertIntoManagedObjectContext:context];

Statement *statement = [NSEntityDescription insertNewObjectForEntityForName:@"Statement" inManagedObjectContext:context];
statement.title = self.enterTextGreenViewTextField.text;

NSNumber  *aNum = [NSNumber numberWithDouble:savingAmount];
statement.amount =aNum;
statement.isIncome = [NSNumber numberWithBool:isIncome];

[month addStatementsObject:statement];

NSError *error;
if (![context save:&error]) {
    FATAL_CORE_DATA_ERROR(error);
    return;
}

NSLog(@"savingStatement ****");

`

#import "Month.h"

NS_ASSUME_NONNULL_BEGIN

@interface Month (CoreDataProperties)

@property (nullable, nonatomic, retain) NSDate *monthOfStatement;
@property (nullable, nonatomic, retain) NSSet<Statement *> *statements;

@end

@interface Month (CoreDataGeneratedAccessors)

- (void)addStatementsObject:(Statement *)value;
- (void)removeStatementsObject:(Statement *)value;
- (void)addStatements:(NSSet<Statement *> *)values;
- (void)removeStatements:(NSSet<Statement *> *)values;

@end

NS_ASSUME_NONNULL_END

And

#import "Statement.h"

NS_ASSUME_NONNULL_BEGIN

@interface Statement (CoreDataProperties)

@property (nullable, nonatomic, retain) NSNumber *amount;
@property (nullable, nonatomic, retain) NSNumber *isIncome;
@property (nullable, nonatomic, retain) NSString *title;
@property (nullable, nonatomic, retain) Month *month;

@end

NS_ASSUME_NONNULL_END

Upvotes: 0

Views: 253

Answers (1)

Carles Estevadeordal
Carles Estevadeordal

Reputation: 1229

Almost right, you have to create the two entities and then bind their relationship:

NSEntityDescription *month = [NSEntityDescription insertNewObjectForEntityForName:@"Month"  inManagedObjectContext:[self managedObjectContext]];
Statement *statement = [NSEntityDescription insertNewObjectForEntityForName:@"Statement" inManagedObjectContext:context];

statement.title = self.enterTextGreenViewTextField.text;

NSNumber  *aNum = [NSNumber numberWithDouble:savingAmount];
statement.amount =aNum;
statement.isIncome = [NSNumber numberWithBool:isIncome];

statement.month=month;

This line i don't know if manually generating the set is necessary, but I do it nonetheless:

NSMutableSet *monthStatements;
if(month.statements){
     monthStatements=[NSMutableSet setWithSet:month.statements];
}else{
     monthStatements=[NSMutableSet alloc] init];
}
[monthStatements addObject:statement];
month.statements = monthStatements;

Finally saving:

NSError *error=nil;
if (![context save:&error]) {
     FATAL_CORE_DATA_ERROR(error);
     return;
}

In my opinion this should work as charm (haven't tried it though) :-)

** Edit:

Fetching:

    NSArray *fetchedObjects;
    NSError *error=nil;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Store" inManagedObjectContext:[self managedObjectContext]];

    [fetchRequest setEntity: entity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat: @"code==%@", code];

    [fetchRequest setPredicate:predicate];

    fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];

You typically will try to fetch the month in case it already exists, and if it doesn't you create it with the code I gave you. I don't know what you mean by creating new relationships though....

Upvotes: 1

Related Questions