hgwhittle
hgwhittle

Reputation: 9426

Core Data add identical object to to-many relationship

Let's say I have an NSManagedObject subclass called Playlist. This Playlistobject has a to-many relationship with another NSManagedObject subclass called Song. Say my Playlist object has one song "song A" associated with it in the relationship.

Given the example, I'm trying to add "song A" to the relationship again, a la adding the same song twice to a playlist.

Here's the code for adding the object to the relationship:

- (void)addSongsObject:(Song *)theSong {
    NSMutableOrderedSet *song = [self mutableOrderedSetValueForKey:@"songs"];
    [mutableSongs addObject:theSong];
}

Where self is the Playlist object. Since there's already an instance of the particular song in the relationship, another instance is not added.

What's the best way to go about doing this with Core Data?

Upvotes: 1

Views: 138

Answers (1)

Nicolas Miari
Nicolas Miari

Reputation: 16246

Like I mentioned in my comment, the solution would be to insert an intermediate, container object in the hierarchy, to represent each (unique) occurrence of a given song in the playlist; let's call it SongOccurrence (SongInstance will do, too).

Because to-many relationships in Core Data are modelled using NSSet (which is unordered but also requires that each element appears at most once, unlike NSArray), you can not add the same instance of a song twice or more.

So, this SongOccurrence object would have a reference to the (unique) Song for which it stands (and that is stored somewhere else, uniquely -say, Library) and possibly an index attribute representing its order in the playlist.

The "reference" can be modelled using a string or int attribute representing the Song object's unique ID (using a relationship would require the inverse to be set, too. This complicates things since a given song can potentially belong to multiple playlists, so it would have to be "to-many").

When playing back the list, you just sort the SongOccurrence instances in the set by their index, retrieve the Song "payload" of each, and play it one after the other.

Upvotes: 2

Related Questions