Question

I've the following problem:

I've an app with a UITableView as root view. In this tableView are different entries and for each entry (which can be created by the user) I also add a persistentstore to my app.

So, when I start the app from scratch (no saved data etc.) and add an entry, the persistentStore is also created and when I click on the tableViewCell, I can save Data in this generated persistentStore. This works fine if I'm creating an entry and also watch the entry during one single run.

BUT

If I close the app and start again, click on the same entry, I get the following error message:

NSFetchRequest *allUsers = [[NSFetchRequest alloc] init];
[allUsers setAffectedStores:[NSArray arrayWithObject:[[self.tableViewContext persistentStoreCoordinator] persistentStoreForURL:storeURL]]];

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSArray initWithObjects:count:]: attempt to insert nil object at objects[0]'

So it seems that I want to add a store which is actually nil, because (I guess so) the system can not find any store under this given storeURL (which is the same as the one where I created a store in the first run).

So I guess the persistentStore isn't there in the second run, so it isn't saved properly in the first run where it was created.

So how can I save a persistentStore, after I've added it, to the persistentStoreCoordinator?

Update:

I think I've identified the main problem. The persistentStoreCoordinator has changed after the first run. So how do I save all these things (managedObjectContext, persistentStoreCoordinator) before closing the app?

Can somebody help me?

Update 2

Here is how I create the store:

    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [searchPaths objectAtIndex:0];
    NSString* storeFileName = [NSString stringWithFormat:@"%@",newItem.name];
    NSURL *storeURL = [NSURL fileURLWithPath:[documentPath stringByAppendingPathComponent:storeFileName]];                            
     NSError* saveToStoreError;
    if(![[self.addContext persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&saveToStoreError]){
     NSLog(@"Error: %@, %@", saveToStoreError, [saveToStoreError userInfo]);
     abort();
    }
    else
    {
      NSError *saveStoreError;
      if(![self.addContext save:&saveStoreError])
      {
           NSLog(@"Saving Data wasn't possible!");
      }
    }

Update 3 So, after a lot of testing here are my results:

  • Creation of the stores works fine. I can create multiple stores and I can access and populate them as long as I'm in a single run of my app.

So something is changing with a restart of my app. I think the error must be associated with the managedObjectContext, the persistentStoreCoordinator or the SAVING of the stores.

Should I change any settings in my app delegate for setting up the managedObjectContext or the persistentStoreCoordinator?

Thanks!

Was it helpful?

Solution 4

It was simply easy.

I didn't set addPersistentStoreWithType after restart in a view where I tried to fetch data from this store.

Sorry for this post. Simply easy ;-) bangingmyheadonthewall

OTHER TIPS

The way you voice your problem leads me to suspect some kind of confusion.

that persistentStore is changing after each restart. Is this the usual case?

Yes it is! a NSPersistentStore is an objective-C object as any other object. As such it is not persistent across launches. You need to recreate it each time.

What's persistent about an NSPersistentStore is the file that it points to. But each time you run your application, you must recreate a new NSPersistentStore object, probably making it point to the same file (defined by the url argument to initWithPersistentStoreCoordinator:configurationName:URL:options:).

So how do you set your storeURL variable?

To save the managed object context, use NSManagedObjectContext's "save:" method after adding a new persistent store & before closing the app. Then, to check if the persistent stores were added properly, use NSPersistentStoreCoordinator "persistentStores" method to determine the valid stores available.

I wonder if the issue isn't the Core Data calls so much as if/when they are being called?

When you "close the app and start again" ... is the app terminated in between, or is it backgrounded? IIRC that will subtly affect what gets called in your App Delegate. Depending on how things are arranged there WRT Core Data, perhaps something is accidentally being called (or missed).

I would be interested in seeing what happens if you trace through every single solitary Core Data related method in your App Delegate (or wherever they may be located), to see if you can catch it more red-handedly. (If there is a minimal test case posted somewhere, please share!)

Take a look at the Window-based application in the Xcode templates.

This creates a whole Core-Data stack for you - persistent store, persistent store coordinator, and managed object context.

Assuming your application doesn't specifically require it, you should only have one persistent store. This is, in effect, the file that the data is written to. Looking at your code, it appears you're trying to create your own store each time you save data.

You should copy the core data stack methods from the template I suggested above. You don't need to refer to the persistent store or the persistent store coordinator yourself. All you need is the managed object context created by the app delegate.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top