0
votes

I have an NSSet of books related in a many to one relationship to an author object in core data.

There is a view where the user may edit these, including leaving them blank. The user can also add new ones. This leads to a situation where:

1) we end up the same number of books, only edited 2) we end up with fewer books, meaning some should be deleted from the NSSet 3) we end up with more books, meaning some should be added to the NSSet.

My original approach was to convert the items into an NSMutableArray, make changes in the mutablearray, convert back to an NSSet and relate the NSSet to the object.

However, while this works in core data's object graph, it does not seem to delete the actual underlying objects in the persistent store.

Alternatively, since NSSet lacks an index, I cannot identify a way to delete a specific object in the NSSet.

The following code edits the names of the books assuming the number of books does not change. However, if the number of books is less after the edit, from what I can tell it does not delete the missing book from the persistent store. It just changes the related objects in core data's object graph. This creates problems when I sync the persistent store to a server.

So basically looking for way to identify and delete an item in an NSSet in the absence of an index. Thanks for any suggestions.

NSSet *booksForAuthor = _author.books;
    NSMutableArray *theBooks = [[booksForAuthor allObjects] mutableCopy];

    NSSortDescriptor *sortDescriptor= [[NSSortDescriptor alloc] initWithKey:@"bid"
                                                 ascending:YES];
    NSArray *booksArray = [theBooks sortedArrayUsingDescriptors:@[sortDescriptor]];
    _numStartingBooks = [booksArray count];
    _booksOnLoad = booksArray; //Now have an array of books before edit
 NSMutableArray <NSString*> *bookNames=[NSMutableArray arrayWithCapacity:20];
   //now collect new set of books from user into array (code omitted)
    [bookNames removeObject:@""];//remove any blanks
    _numBooks = [bookNames count];//number of books after edit
    int i;
        for (i = 0; i < _numStartingBooks; i++) {
            [theNewBooks addObject:_booksOnLoad[i]];
            theNewBooks[i].name = bookNames[i];
        }    
     NSSet *theBookSet = [NSSet setWithArray:theNewBooks];
     _author.books = theBookSet;

At this point, we have set the NSSet to the new number of books, but from what I can tell, not deleted the underlying extra managed objects present at the beginning.

1

1 Answers

1
votes

I think maybe your whole approach and architecture is overly complicated.

First of all, please download this sample project from Apple. In case Apple breaks the link, search for it. It is called CoreDataBooks. Take a day or two to study it. You see it is written in Objective-C, like your code. And, like your project, it has books and authors. CoreDataBooks is pretty much the perfect example for you!

I am recommending this because it appears that your code interposes these NSMutableSets and NSMutableArrays between your view and your model (Core Data). You shouldn't need to do that. As a matter of fact, I just searched that Apple project for the symbols NSSet, NSMutableSet, NSArray and NSMutableArray. I found only one, an array of sort descriptors! There are no sets or arrays of authors or books anywhere in Apple's sample project.

Regarding synchronizing data to a server, this is done by creating a secondary managed object context connected to the same persistent store. In a proper design, it will not be involved with your user interface at all, so don't worry about it for now. Get your user interface working with the local Core Data store first, as in CoreDataBooks, and by then you will have learned much and will be in a much better position to tackle syncing :)