Any idea why
//should save the object context.
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(#"SAVE ERROR");
}
when implemented in a view controller(accessed via a drill down tableview) won't properly save the information? I am passing the moc from the beginning (rootview hands off to tableview, tableview recursively passes it to itself until calls uiview) and any additions I do show up in the table if I pop/push the tableview(unfortunately reloadData in viewWillAppear doesn't want to update it).
Should I be passing the managedObject instead and fetching the context from that?
Since I was manually creating the sqlite entries in the code on load, I was also manually deleting it in the persistentStoreCoordinator each time the program started. Unfortunately, I forgot about that aspect.
Related
Before anyone suggests, we are using one managedObjectContext for [context save:&error];
We are saving a new object in Core Data with iOS5.
The issue is, the first time we save a new object, NSManagingContextDidSaveChangesNotification fires and the [[notification userInfo] objectForKey:NSUpdatedObjectsKey] gives back an unpopulated object. In iOS6, objectForKey:NSUpdatedObjectsKey is populated.
Afterwards when we save objectForKey:NSUpdatedObjectsKey is populated.
The context we are always using is [[UIApplication sharedApplication] delegate].mainDocument.managedObjectContext.
So the issue is, the first time [context save:&error] is called, nothing is saved to the db. But it has been saved to the object, so the next time [context save:&error] is called it gets put in the db.
Does anyone have any info on this. I've heard tell of bugs in CoreData in iOS5 , so if anyone has any advice we would appreciate it.
Check these items in the given order:
Make sure the object is already populated when you save it the first time (e.g. NSLog).
Make sure you query the notifications's userInfo properly.
Make sure at this point that the physical database does not contain the proper information (e.g. via sqlite3 command line tool)
Make sure you output the correct object whenever you check if it is populated or not.
I need to fire fetch request controller after finish the updating. Is their any method to control this.
Reason is some parent entity have child entity called "Image". This use for store the image. This images are download separately.
Because of this reason i can't get images when fetch request controller fire(image download not finished).
Ask the fetchedResultsController to refetch by calling performFetch.
NSError *error;
[self.fetchedResultsController performFetch:&error];
I have a MOC created in my AppDelegate class. I have a MOC property in my RootView which is set by the AppDelegate with something like:
rootView.managedObjectContext = self.managedObjectContext;
This rootView creates at some time a ModalView and sets there a MOC property also by the same way.
Everything works fine. I can create new managed objects, the views can access them and delete them.
Until the point i make a [self.managedObjectContext save:&error] (in the AppDelegate class when the app moves into background).
After this, if i create a new managed object in the rootView, i can not delete this new object through the modal view with something like: [self.managedObjectContext deleteObject:managedObject]
The app crashes. Sometimes I had an error message in the console like: NSManagedObjectContext cannot delete objects in other contexts.
So it seems that after the save the MOC changes somehow.
What is happening there, what did I miss.
I am using iOS 4.1.
Thx and cheers,
Ben
Can't tell much without code but I can take a wild guess based on your description.
If you have a custom getter method for the managedObjectContext property in the app delegate that creates the context if it is nil, you might have messed it up causing the accessor to generate a new context each time.
For example, the Xcode template accessors looks like:
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
If you did something similar but left out the test for the existing context, you would get a new context each time self.managedObjectContext is called.
Ok, so this is really strange: Two days ago i quitted working on the project because of the MOC problem. Yesterday evening I started again working on it. I absolutely did not change anything on the code and just wanted to reproduce the error to debug it. And what happend? The error did not appear again. So it seems to that restarting the computer "fixed" the problem. Since then the error did never ever happen again, even after hours of working and testing.
Thanks a lot for help anyway.
Bye,
Ben
In my iPhone app, I have an NSFetchedResultsController showing User objects in a UITableView. The User Objects have 0-many Log objects. A summary of the Log objects are shown together with their User object in the UITableView.
My app uses a tab bar, so user input in the logging tab require that the user tab's NSFetchedResultsController is triggered to reload.
So far I do it by writing to the User object:
log.user = nil;
log.user = [User current]; // Same as before. Just triggering a reload.
NSError *error = nil;
[myManagedObjectContext save:&error];
This works fine, but seems a bit like a hack.
Is there a better way to do this? Like specifying that changes in the Log object should propagate to the User object too?
[myFetchedResultsController performFetch:&error];
But why would you want to do this? It should only reload when there is new data for it to fetch. If there is new data then a save of the NSManagedObjectContext is the right action.
What is your underlying goal?
I'm new to this Core Data business.
I got a UITableViewController hooked up with a NSFetchedResultsController. In viewDidLoad, I fire a request to get necessary data from the server, then use [self.fetchedResultsController performFetch:&error] to update the table view. All works fine until that point.
Now I want to move the data fetching stuff to another thread, so after the app received a NSArray object from the server, it performs the didFinishFetchingItems selector on the main thread. In that selector, I save the NSArray to the Core Data store and have the fetchedResultsController perform a fetch. No data show up, although a NSLog reveals that the data is still there (e.g. [[fetchedResultsController fetchedObjects] count] returns 100). I have to put a [self.tableView reloadData] at the end of the method to refresh the table view manually.
My question is: What have I done wrong? Why did I need to do the table view refreshing manually?
You should not touch your NSFetchedResultsController in a non-main thread, that is not a thread-safe operation.
If you are having a long delay on fetching then you need to do a background fetch using a separate NSManagedObjectContext. If you perform a separate fetch in the background it will load the data into cache and then the NSFetchedResultsController will hit the cache instead of disk, speeding up retrieval on the main thread.
You do not need to refresh anything manually; fetchedResultsController does that for you.
What you need to do is to implement NSFetchedResultsControllerDelegate for some object, and set that object as the delegate for your fetchedresultscontroller.
See this about what you need to implement. If your model is simple, you can pretty much copy-paste that code into your delegate and everything works.
The important thing is to keep both the resultscontroller and other pieces of code working against the same managed object context. This is how the resultscontroller can pick up the changes. But, in Core Data guide, there are some caveats about multithreading, so make sure you have your threading bases covered and then all works.