title: Core Data Many-To-Many relationship
body: <p>I have a sample app that I am working through some Swift &amp; Core Data work before moving the code over to the real app.  I have a need for a Many-To-Many relationship.  The sample below shows you the One-To-Many that works just fine using the default boiler coded when you create a new app in Xcode and selecting Core Data.</p>
  
  <p><img src="https://i.stack.imgur.com/KtjWo.png" alt="enter image description here"></p>
  
  <pre><code>import UIKit
  import CoreData
  
  class ViewController: UIViewController {
  
      let managedObjectContext    = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext
      let appDelegate:AppDelegate =  UIApplication.sharedApplication().delegate as AppDelegate
  
      var teamInformation:TeamInformation?
      var playerInformation:PlayerInformation?
      var position:Position?
      var rosterInformation:RosterInformation?
      var positionsSet = NSMutableSet()
  
  
      override func viewDidLoad() {
          super.viewDidLoad()
          // Do any additional setup after loading the view, typically from a nib.
  
          loadData()
      }
  
      func loadData() {
  
          //Team Information
          var newTeamInformation1 = NSEntityDescription.insertNewObjectForEntityForName("TeamInformation", inManagedObjectContext: managedObjectContext!) as TeamInformation
          newTeamInformation1.teamName = "Team 1"
  
          var newTeamInformation2 = NSEntityDescription.insertNewObjectForEntityForName("TeamInformation", inManagedObjectContext: managedObjectContext!) as TeamInformation
          newTeamInformation2.teamName = "Team 2"
  
          var newTeamInformation3 = NSEntityDescription.insertNewObjectForEntityForName("TeamInformation", inManagedObjectContext: managedObjectContext!) as TeamInformation
          newTeamInformation3.teamName = "Team 3"
  
          var newTeamInformation4 = NSEntityDescription.insertNewObjectForEntityForName("TeamInformation", inManagedObjectContext: managedObjectContext!) as TeamInformation
          newTeamInformation4.teamName = "Team 4"
  
          var newTeamInformation5 = NSEntityDescription.insertNewObjectForEntityForName("TeamInformation", inManagedObjectContext: managedObjectContext!) as TeamInformation
          newTeamInformation5.teamName = "Team 5"
  
          //Save Data
          appDelegate.saveContext()
  
          //Player Information
          var newPlayerInformation1 = NSEntityDescription.insertNewObjectForEntityForName("PlayerInformation", inManagedObjectContext: managedObjectContext!) as PlayerInformation
          newPlayerInformation1.firstName = "Player 1"
  
          var newPlayerInformation2 = NSEntityDescription.insertNewObjectForEntityForName("PlayerInformation", inManagedObjectContext: managedObjectContext!) as PlayerInformation
          newPlayerInformation2.firstName = "Player 2"
  
          var newPlayerInformation3 = NSEntityDescription.insertNewObjectForEntityForName("PlayerInformation", inManagedObjectContext: managedObjectContext!) as PlayerInformation
          newPlayerInformation3.firstName = "Player 3"
  
          var newPlayerInformation4 = NSEntityDescription.insertNewObjectForEntityForName("PlayerInformation", inManagedObjectContext: managedObjectContext!) as PlayerInformation
          newPlayerInformation4.firstName = "Player 4"
  
          var newPlayerInformation5 = NSEntityDescription.insertNewObjectForEntityForName("PlayerInformation", inManagedObjectContext: managedObjectContext!) as PlayerInformation
          newPlayerInformation5.firstName = "Player 5"
  
          //Save Data
          appDelegate.saveContext()
  
          //Positions
          var newposition1 = NSEntityDescription.insertNewObjectForEntityForName("Position", inManagedObjectContext: managedObjectContext!) as Position
          newposition1.position = "C"
  
          var newposition2 = NSEntityDescription.insertNewObjectForEntityForName("Position", inManagedObjectContext: managedObjectContext!) as Position
          newposition2.position = "LW"
  
          var newposition3 = NSEntityDescription.insertNewObjectForEntityForName("Position", inManagedObjectContext: managedObjectContext!) as Position
          newposition3.position = "RW"
  
          var newposition4 = NSEntityDescription.insertNewObjectForEntityForName("Position", inManagedObjectContext: managedObjectContext!) as Position
          newposition4.position = "G"
  
          var newposition5 = NSEntityDescription.insertNewObjectForEntityForName("Position", inManagedObjectContext: managedObjectContext!) as Position
          newposition5.position = "D"
  
          //Save Data
          appDelegate.saveContext()
  
          //Add players to Team 1 Roster
          var newPlayerToAddToRoster1 = NSEntityDescription.insertNewObjectForEntityForName("RosterInformation", inManagedObjectContext: managedObjectContext!) as RosterInformation
          newPlayerToAddToRoster1.rosterInformationToPlayerInformationRelationship = newPlayerInformation1
          newPlayerToAddToRoster1.rosterInformationToTeamInformationRelationship   = newTeamInformation1
          newPlayerToAddToRoster1.rosterInformationToPositionRelationship          = newposition4
          newPlayerToAddToRoster1.playerNumber = "29"
  
          //Save Data
          appDelegate.saveContext()
  
          var newPlayerToAddToRoster2 = NSEntityDescription.insertNewObjectForEntityForName("RosterInformation", inManagedObjectContext: managedObjectContext!) as RosterInformation
          newPlayerToAddToRoster2.rosterInformationToPlayerInformationRelationship = newPlayerInformation2
          newPlayerToAddToRoster2.rosterInformationToTeamInformationRelationship   = newTeamInformation1
          newPlayerToAddToRoster2.rosterInformationToPositionRelationship          = newposition1
  
          newPlayerToAddToRoster2.playerNumber = "5"
  
          //Save Data
          appDelegate.saveContext()
  
      }
  }
  </code></pre>
  
  <p>When I examine the tables in SQLite3, everything is working as expected and the relationships (ZROSTERINFORMATION) are functioning. So the next step is to move the Position Entity to Many.  A play in the roster can have many positions and a Roster has many players.</p>
  
  <pre><code>sqlite&gt; select * from ZPLAYERINFORMATION;
  1|1|1|Player 4|
  2|1|1|Player 3|
  3|1|2|Player 2|
  4|1|2|Player 1|
  5|1|1|Player 5|
  sqlite&gt; select * from ZPOSITION;
  1|2|2|C
  2|2|1|D
  3|2|1|LW
  4|2|1|RW
  5|2|2|G
  sqlite&gt; select * from ZROSTERINFORMATION;
  1|3|1|4|5|3|29
  2|3|1|3|1|3|5
  sqlite&gt; select * from ZTEAMINFORMATION;
  1|4|1|Team 3
  2|4|1|Team 4
  3|4|3|Team 1
  4|4|1|Team 5
  5|4|1|Team 2
  </code></pre>
  
  <p>When I change to rosterInformationToPositionRelationship  to Many-To-Many, it changes the relationship to an NSSet.</p>
  
  <p><img src="https://i.stack.imgur.com/tP2J3.png" alt="enter image description here"></p>
  
  <p>I thought by doing the following would satisfy the NSset:</p>
  
  <pre><code>//Add players to Team 1 Roster
  var newPlayerToAddToRoster1 = NSEntityDescription.insertNewObjectForEntityForName("RosterInformation", inManagedObjectContext: managedObjectContext!) as RosterInformation
  newPlayerToAddToRoster1.rosterInformationToPlayerInformationRelationship = newPlayerInformation1
  newPlayerToAddToRoster1.rosterInformationToTeamInformationRelationship   = newTeamInformation1
  
  //Add multiple positions...
  newPlayerToAddToRoster1.rosterInformationToPositionRelationship.setByAddingObject(newposition4)
  newPlayerToAddToRoster1.rosterInformationToPositionRelationship.setByAddingObject(newposition5)
  
  //Add player number
  newPlayerToAddToRoster1.playerNumber = "29"
  </code></pre>
  
  <p>But by looking at the SQLite3 tables, but the player added should have 2 positions ("G" &amp; "D") So it appears it's only taking the last entry.</p>
  
  <pre><code>sqlite&gt; select * from ZROSTERINFORMATION;
  1|3|1|2|2|29
  2|3|1|3|2|5
  sqlite&gt; select * from ZPLAYERINFORMATION;
  1|1|1|Player 3|
  2|1|2|Player 1|
  3|1|2|Player 2|
  4|1|1|Player 4|
  5|1|1|Player 5|
  sqlite&gt; select * from ZPOSITION;
  1|2|1|C
  2|2|1|D
  3|2|1|LW
  4|2|1|RW
  5|2|1|G
  </code></pre>
  
  <p>So I tried this:</p>
  
  <pre><code>//Add players to Team 1 Roster
  var newPlayerToAddToRoster1 = NSEntityDescription.insertNewObjectForEntityForName("RosterInformation", inManagedObjectContext: managedObjectContext!) as RosterInformation
  newPlayerToAddToRoster1.rosterInformationToPlayerInformationRelationship = newPlayerInformation1
  newPlayerToAddToRoster1.rosterInformationToTeamInformationRelationship   = newTeamInformation1
  
  //Add multiple positions...            
  positionsSet.setByAddingObject(newposition4)
  positionsSet.setByAddingObject(newposition5)        
  newPlayerToAddToRoster1.rosterInformationToPositionRelationship.setByAddingObject(positionsSet)
  
  //Add player number
  newPlayerToAddToRoster1.playerNumber = "29"
  </code></pre>
  
  <p>When I check the SQLite3, I can see that once again it's only displaying the last object in the positionsSet NSMutableSet...</p>
  
  <p>What am I doing wrong?</p>
  
  <pre><code>sqlite&gt; select * from ZPLAYERINFORMATION;
  1|1|1|Player 5|
  2|1|2|Player 1|
  3|1|1|Player 3|
  4|1|2|Player 2|
  5|1|1|Player 4|
  sqlite&gt; select * from ZPOSITION;
  1|2|1|RW
  2|2|1|G
  3|2|1|D
  4|2|1|C
  5|2|1|LW
  sqlite&gt; select * from ZTEAMINFORMATION;
  1|4|1|Team 5
  2|4|3|Team 1
  3|4|1|Team 2
  4|4|1|Team 3
  5|4|1|Team 4
  sqlite&gt; select * from ZROSTERINFORMATION;
  1|3|1|2|2|29
  2|3|1|4|2|5
  </code></pre>
  
  <p>When I change to the following code:</p>
  
  <pre><code>positionsSet.addObject(newposition4)
  positionsSet.addObject(newposition5)
  
  
  println("positionsSet \(positionsSet.description)");
  </code></pre>
  
  <p>Here is the output:</p>
  
  <pre><code>positionsSet {(
      &lt;One_To_Many.Position: 0x7fef8b492370&gt; (entity: Position; id: 0xd000000000100004 &lt;x-coredata://AE608FC7-7683-490E-A6E1-17D4F058D54A/Position/p4&gt; ; data: {
      position = G;
      positionToRosterInformationRelationship =     (
      );
  }),
      &lt;One_To_Many.Position: 0x7fef8b492540&gt; (entity: Position; id: 0xd000000000140004 &lt;x-coredata://AE608FC7-7683-490E-A6E1-17D4F058D54A/Position/p5&gt; ; data: {
      position = D;
      positionToRosterInformationRelationship =     (
      );
  })
  )}
  </code></pre>
  
  <p>What am I missing?</p>
  
  <pre><code>class RosterInformation: NSManagedObject {
  
      @NSManaged var playerNumber: String
      @NSManaged var rosterInformationToPlayerInformationRelationship: PlayerInformation
      @NSManaged var rosterInformationToPositionRelationship: NSSet
      @NSManaged var rosterInformationToTeamInformationRelationship: TeamInformation
  
  }
  
  class Position: NSManagedObject {
  
      @NSManaged var position: String
      @NSManaged var positionToRosterInformationRelationship: NSSet
  
  }
  
  class TeamInformation: NSManagedObject {
  
      @NSManaged var teamName: String
      @NSManaged var teamInformationToRosterInformationRelationship: NSSet
  
  }
  
  class PlayerInformation: NSManagedObject {
  
      @NSManaged var firstName: String
      @NSManaged var lastName: String
      @NSManaged var playerInformationToRosterInformationRelationship: NSSet
  
  }
  </code></pre>