1
votes

Happy New year.

Iam working with a app where data is saved by using core data. The app contains a calendar module and the user is allowed to skip back/forth between dates by two buttons(nextDay, previousDay). Each day contains som information which I fetch from a webservice, and therefore I would like to fetch a large part of the data(the next 14 days) in the background while the users uses the calendar.

So here is my approach:

The data of the first day is fetched by the main thread and save to the persistent store and presented to the user. Then a NSThread is started in the background with a new nsmanagedcontext fetching data and when the all data is fetched it is saved to the persistent store.

However while this background thread is running, the user has the option to skip to the next day or the previous day, and if there is no data the main thread will fetch the data and save it to the persistent store. This presents the possibility of both threads fetching the same data and saving it to the persistent store. But as I understood this approach should not be a problem as I use a new nsmanangedcontext for the background thread.

But sometimes I get the following error The operation couldn’t be completed. (Cocoa error 133020.) and then the main thread cannot save to the persistent store.

I have tried using only one nsmanagedcontext shared between the threads, but this sometime causes one of the threads to stop and never move on.

I have spent a lot of hours reading different forums/blogs and hope anyone can help or guide me in the right direction.

regards

SOLVED WITH HELP: The error i was getting was due to errors during merging when saving to my persistent store. I was able to solved it by changing the merging policy when saving. The following snippet shows my method for init of nsmanagedcontext. Where the bold shows the setting of policy. I can do this because the data which i am fetching is the same, no matter if it is the main thread or the background thread.

- (NSManagedObjectContext *)managedObjectContext
{
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil)
    {
        __managedObjectContext = [[NSManagedObjectContext alloc] init];
        [__managedObjectContext setPersistentStoreCoordinator:coordinator];
          **[__managedObjectContext setMergePolicy:NSOverwriteMergePolicy];**
    }
    return __managedObjectContext;
}
1
Not really related to your question but it really helps if you break up your answer into smaller chunks (vertical white space is your friend) possibly including code snippets (highlighting and colours are also cool) etc. When I clicked on your question my first thought is "I'm not reading all that" - Paul.s
Hi Paul, The editor removed my spaces, i dont know if I need to do something ot it is because I am using chrome - Bjarke
Or maybe I was just to fast when writing my post because of all the headache I got from my issue:P - Bjarke

1 Answers

1
votes

According to http://developer.apple.com/library/ios/#documentation/cocoa/Reference/CoreDataFramework/Miscellaneous/CoreData_Constants/Reference/reference.html your error code represents a NSManagedObjectMergeError.

Since your always fetching the same data, I'm assuming it should be the same whether you got it from the background thread or your main thread, so you should be able to change your merging policy from it's default NSErrorMergePolicy to NSOverwriteMergePolicy which will overwrite any conflicted object with the new data (again, assuming they are the same, this wouldn't be a problem).

You can find more on merge policies here: http://developer.apple.com/library/ios/#documentation/CoreData/Reference/NSMergePolicy_Class/Reference/Reference.html#/