7
votes

I'm using UIManagedDocument to manage my data. I create the model and use it, and everything seems to be working, but my changes aren't being written back to the SQLite store.

The documentation for UIManagedDocument says that the autosave should take care of persisting the data to the database, but that doesn't seem to be happening.

    NSManagedObjectContext *moc = [doc managedObjectContext];
    NSError *error = nil;
    MyItem *itemToAdd = (MyItems *)[moc existingObjectWithID:(NSManagedObjectID *)itemsID error:&error];

This fetches the object I want to add (and succeeds).

   [itemContainer addItemsObject:itemToAdd];
   [doc updateChangeCount:UIDocumentChangeDone];

This adds the item to an items collection in another object, and then tells the document that I'm done making changes.

I'd expect some time shortly after this to see the change written to the Core Data store, but watching in Instruments, I see that it never happens.

The items collection is an NSOrderedSet, and because of comments on this item:

Exception thrown in NSOrderedSet generated accessors

I've added an addItemsObject: to the object that holds the collection:

- (void)addItemsObject:(MyItem *)value 
{
    NSMutableOrderedSet* tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.items];
    [tempSet addObject:value];
    self.items = tempSet;
}

Perhaps something is going wrong with Core Data being informed that the items collection has changed, but I don't see how.

3
With Instruments, I can see that data is being written to the Core Data Cache. But it doesn't show up in the Core Data Saves instrument, and if I kill and restart the app, my changes are gone.stevex
I found my problem. Turns out I had an error with the object I was attempting to add - I missed a required property - and without overriding handleError there's no indication that there's a problem. Blogged about it here: blog.stevex.net/2011/12/…stevex

3 Answers

10
votes

I found my problem. Turns out I had an error with the object I was attempting to add - I missed a required property - and without overriding handleError there's no indication that there's a problem.

Blogged about it here: http://blog.stevex.net/2011/12/uimanageddocument-autosave-troubleshooting/

1
votes

In my method where I fetch data from server, I first create the Entities and after that I call these two methods to save the changes to the document immediately:

[self.document updateChangeCount:UIDocumentChangeDone];
[self.document savePresentedItemChangesWithCompletionHandler:^(NSError *errorOrNil) {
            ...
        }];
1
votes

Key take aways / summary from @stevex's link :

Make sure to call the UIManagedDocument's -updateChangeCount method or trigger a change that is registered with the document's undoManager. Otherwise the document doesn't think it needs to save anything.

Also, subclassing some key methods will allow you to see when autosaving occurs and if there are errors.

- (id)contentsForType:(NSString *)typeName error:(NSError * _Nullable __autoreleasing *)outError {

    id retVal = [super contentsForType:typeName error:outError];
    NSLog(@"Autosaving document. contentsForType at fileURL %@ error %@", self.fileURL, *outError);
    return retVal;
}


- (void)handleError:(NSError *)error userInteractionPermitted:(BOOL)userInteractionPermitted {
    [super handleError:error userInteractionPermitted:userInteractionPermitted];
    NSLog(@"ManagedDocument handleError: %@  %@", error.localizedDescription, error.userInfo);
}