Reputation: 83
Core Data Noob here.
I have a project, it saves data to a single entity no problemo. However, because the entity has way too many properties (over 100) it gets a warning that I need to normalize it. OK, so i create a second entity to store more data with To-One relationships both ways.
Problem is that when i try to save data, data saves and reloads to the first entity, but will not save or reload from the second. I must be missing something simple.
Here is some code:
//ViewDidLoad
- (void)viewDidLoad
{
if (managedObjectContext == nil) {
managedObjectContext = [(CoreDataStuffAppDelegate *) [[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(@"After managedObjectContext: %@", managedObjectContext);
}
// [self addRecord];
[super viewDidLoad];
if ([self fetchData]) {
NSLog(@"after self fetchData patientArray count is %i", [parentArray count]);
if ([parentArray count] == 1) {
Parent *parentInfo = (Parent *)[parentArray objectAtIndex:0];
parentItem1.text = parentInfo.Mother;
NSLog(@"fetching on load %i", [parentArray count]);
//Try 1: just going after the relationship route (FAIL: cuz data wont store. stays null)
// childItem1.text = parentInfo.ParentToChild.Kid;
// Try 2: going the route of directly talking to the second entity
childItem1.text = child.Kid;
}
}
// Save Record
- (void)saveRecord{
if (managedObjectContext == nil) {
NSLog(@"there is no context, arrg");
}
NSLog(@"array count is %i", [parentArray count]);
if ([parentArray count] == 1) {
NSManagedObjectContext *context = managedObjectContext;//[parent managedObjectContext];
NSLog(@"context 1 is: %@", context);
Parent *parentInfo = (Parent *)[parentArray objectAtIndex:0];
parentInfo.Mother = parentItem1.text;
NSLog(@"data says: %@", parentInfo.Mother);
NSLog(@"text syas: %@", parentItem1.text);
// Try 1, save it through the child relationship thing. (failed)
// parentInfo.ParentToChild.Kid = childItem1.text;
// NSLog(@"childSave says: D: %@ T: %@", parentInfo.ParentToChild.Kid , childItem1.text);
// Try 2. from Resipeas app
if (!child) {
self.child = [NSEntityDescription insertNewObjectForEntityForName:@"Child" inManagedObjectContext:context];
[parent addChildObject:child];
NSLog(@"I hit the child");
}
child.Kid = childItem1.text;
NSLog(@"1: childSave says: D: %@ T: %@", parentInfo.ParentToChild.Kid , childItem1.text);
NSLog(@"2: childSave says: D: %@ T: %@", child.Kid , childItem1.text);
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"context 2 is: %@", context);
NSLog(@"major fail %@", [error localizedDescription]);
// abort();
}
}
NSLog(@"saving stuff");
}
// FetchData
- (BOOL)fetchData {
NSLog(@"doing the fetch");
BOOL returnResult = FALSE;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
if (managedObjectContext == nil)
{
NSLog(@"ok making a new managed object context");
managedObjectContext = [(CoreDataStuffAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Parent" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:1];
NSError *error;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
if (mutableFetchResults == nil) {
NSLog(@"Fetching Error");
} else {
[self setParentArray:mutableFetchResults];
returnResult = TRUE;
NSLog(@"Fetching went well");
}
[mutableFetchResults release];
[fetchRequest release];
return (returnResult);
}
Upvotes: 1
Views: 1890
Reputation: 64428
Okay, firstly, I think you have a conceptual problem here because I have never seen the need for an entity with 100 attributes. Most entities have a around a half-dozen attributes and I think the most I've ever seen was around 20.
Core Data is first and foremost an object graph management system with persistence tossed in as an option. It is intended to implement the model layer of a Model-View-Controller(MVC) design. As such, Core Data is primarily about modeling data not storing it.
Entities are intended to represent some real-world object, condition or event. There aren't a lot of real-world things that have a 100 attributes. E.g. You want to make a detailed model of a person. You want things like first name, last name, address(with attributes for each address component), driver's license# and date of issue, place of employment with address, social security number etc. If you tried to cram all that into one Person
entity you could end up with a dozens of attributes. However, if you look closely at the data you are modeling and the relationships within the data, you would note that in the real world, addresses, driver's license, places of employment etc are not actually attributes of real people but rather other real-objects related to real people. Therefore, the best approach would be to break out the attributes for those objects into separate entities and create relationships to the Person entity. This makes model more realistic as well. After all, more than one person can live at the same address or work at the same place.
So, you probably need to start over from scratch and rethink your data model design.
Make sure you understand the difference between entities and managedObjects. Entities are abstract and serve merely to define keys, value types and relationships for managedObjects. Entities are to managedObjects as classes are to instances.
You have two other problems:
(1) You can only use the dot syntax accessor forms e.g parentInfo.ParentToChild.Kid
if you have defined custom NSManagedObject subclasses for your entities. Otherwise, you are using generic NSManagedObject instances and must use the key-value methods e.g. [parent setvalue:forKey]
.
(2) A fetch returns only objects of one entity. So if you have a Parent entity and a Child entity. Each fetch returns instances of either Parent or Child but never both (unless they both inherit from the fetch's entity.)
Upvotes: 2