views:

70

answers:

2

Hi guys, I'm developing an application, which parses XML ant put data to CoreData. I want it to start quickly, so I load data from CoreData first, and after load and parse XML in other thread. The problem is that when the app starts first time CoreData is empty and I start to parse:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"SlideItem" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];

// Execute the fetch -- create a mutable copy of the result.
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];

if (mutableFetchResults == nil) 
{
    // Handle the error.
    NSLog(@"mutableFetchResults == nil"); 
}

NSLog(@"mutableFetchResults count = %d", [mutableFetchResults count] );

if ([mutableFetchResults count] == 0 ) // if DB is empty
{
    [self loadAndParse]; // here I do it in the main thread
    //so my CoreData is filled with data here
}
//but if try to execute my request again like this:
mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
//it is empty again

How can I do it? thanks

+2  A: 

You have to merge the changes from the other context in the thread where the xml is parsed. Until you do that, the context on the main thread doesn't know what was changed.

Use:

-[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:]

or

-[NSManagedObjectContext refreshObject:mergeChanges:]
TechZen
Thanks, How can I do it? I'm new to objective-c so need it clear,I tried [NSManagedObjectContext refreshObject: managedObjectContext mergeChanges:YES]; but it's not working(
Burjua
And BTW it's the same thread))
Burjua
`refreshObject:` is called from the context making the change. You don't pass the context, you pass the object changed. `mergeChanges` is called after you register context A for the `ContextDidSave` notification from context B.
TechZen
If you're using only one thread you might as well use a single context. I may have misunderstood because of the mention of thread. Are you using more than one context?
TechZen
Ok, thanks, I had to change my architecture completely, but I solve the problem
Burjua
+1  A: 

If you are loading your parsed data into a different managed object context than the one you use in the snipped above, then you need to do as TechZen suggests and merge the changes between these contexts. Apple provides a good explanation in their CoreDataBooks example. Look at the RootViewController.m file and start reading the comments for the addViewController:didSave: method. All of the code is there to merge changes between two discrete managed object contexts (in CoreDataBooks they create a separate managed object context to edit a new book entity).

If, on the other hand, your loadAndParse: uses the same managed object context as the code above, then I don't think you are actually successfully adding anything to the Core Data store. In that case the problem is probably with the loadAndParse: method.

Tim Isganitis