title: Core data one to many relationship in swift
body: <p>I have been searching for days on how to work with one to many relationships.
  But I can't get it figured out.</p>
  
  <p>I am working on a app which stores the grades of a subject. So one subject has a to-many relationship with grades. All the data is currently stored in a array.</p>
  
  <p><code>var vakken: [(naam:String, voorkeurGemiddelde:Double, wegingGemiddelde:Double, cijfer:[Double], weging:[Double], gemiddelde:Double)] = []</code><br>
  Where the the [Double]'s  - Cijfer and weging- are attributes of a grade. </p>
  
  <p><a href="https://i.stack.imgur.com/sOo22.png" rel="noreferrer"><img src="https://i.stack.imgur.com/sOo22.png" alt="dataModel"></a></p>
  
  <p>I currently have the following for saving the data: </p>
  
  <pre><code> let context = AppDelegate().managedObjectContext
  
      // Create subject
      let entitySubject = NSEntityDescription.entityForName("Subject", inManagedObjectContext: context)
      let Subject = NSManagedObject(entity: entitySubject!, insertIntoManagedObjectContext: context)
  
      // Populate subject
      Subject.setValue(vakken.last!.naam, forKey: "name")
      Subject.setValue(vakken.last!.voorkeurGemiddelde, forKey: "voorkeurGemiddelde")
      Subject.setValue(vakken.last!.wegingGemiddelde, forKey: "wegingNP")
      Subject.setValue(vakken.last!.gemiddelde, forKey: "gemiddelde")
  
      for var j = 0; j &lt; vakken.last!.cijfer.count-1; j++ {
  
          let Grade = NSEntityDescription.insertNewObjectForEntityForName("Grade", inManagedObjectContext: context)
  
          Grade.setValue(vakken.last!.cijfer[j], forKey: "cijfer")
          Grade.setValue(vakken.last!.weging[j], forKey: "weging")
  
          Subject.setValue(NSSet(object: Grade), forKey: "grade")
      }
  
      do{
          try context.save()
      }catch{
          print("error")
      }
  </code></pre>
  
  <p>I am using the data in a tableView.
  I have seen in some tutorials that the use: <code>var vakken = [NSManagedObject]()</code> and then use it in a tableview.<br>
  <strong>1. But is this also possible with the model I have, and should I use it?</strong></p>
  
  <p>I first thought was to just save the data when the app terminates, so I would have the code in the app delegate, and then just retrive it when the app starts.</p>
  
  <p><strong>2. But how would I get the array to the appdelegate and would this be smart?</strong></p>
  
  <p>And for fetching the data I have this:</p>
  
  <pre><code>  let fetchRequest = NSFetchRequest(entityName: "Subject")
  
  //        // Add Sort Descriptor
  //        let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)               
  //        fetchRequest.sortDescriptors = [sortDescriptor]
  
  
          let context = Appdelegate().managedObjectContext
  
          // Execute Fetch Request
          do {
              let result = try context.executeFetchRequest(fetchRequest)
              print(result)
          } catch {
              let fetchError = error as NSError
              print(fetchError)
          }
  </code></pre>
  
  <p><strong>3. But how would I get from the result my array back or if I use NSManagedObject how can I refer to the attributes and in most particular the grades.</strong></p>
  
  <p>I also sort my array by name which can be A-Z or Z-A, and I sort by average which can be 10-1 or 1-10. I have the code to sort it in my array.<br>
   <strong>4. But I don't know how to sort this with core data.</strong> </p>
  
  <p>I have also seen a tutorial where they made a class for the attributes <a href="https://stackoverflow.com/questions/29825604/how-to-save-array-to-coredata">link</a>.
  So I made one my self:   </p>
  
  <pre><code>    import UIKit
  import CoreData
  import Foundation
  
  class Subject: NSManagedObject {
      @NSManaged var gemiddelde: Double
      @NSManaged var name: String
      @NSManaged var voorkeurGemiddelde: Double
      @NSManaged var wegingNP: Double
      @NSManaged var Grades: NSSet
  }
  
  class Grade: NSManagedObject {
      @NSManaged var cijfer: Double
      @NSManaged var weging: Double
      @NSManaged var subject: Subject
  }
  
  extension Subject {
      func addTagObject(value:Grade) {
          let items = self.mutableSetValueForKey("grade");
          items.addObject(value)
      }
  
      func removeTagObject(value:Grade) {
          let items = self.mutableSetValueForKey("grade");
          items.removeObject(value)
      }
  }
  </code></pre>
  
  <p><strong>5. But I don't know if I need it nor how to use it?</strong></p>
  
  <p>If you have any advise, tips, know good tutorials or know one of these questions. 
  Your help would be appreciated.</p>
  
  <p>If you need any more information just let me know. :)</p>
  
  <p>Update:</p>
  
  <p>I have this code to get the object of the subject witch is clicked.</p>
  
  <pre><code>if let indexPath = self.tableView.indexPathForSelectedRow {
                  let object = self.fetchedResultsController.objectAtIndexPath(indexPath)
                  let controller = segue.destinationViewController as! VakTableViewController
                  controller.vak = object as! Subject
  
              }
  </code></pre>
  
  <p>And this is the code on the receiving end:</p>
  
  <pre><code> var vak: Subject! {
      didSet {
          // Update the view.
          cijfers = vak.valueForKeyPath("grades.cijfer")!.allObjects as! [Double]
          wegingen = vak.valueForKeyPath("grades.weging")!.allObjects as! [Double]
          self.tableView.reloadData()
      }
  }
  
  var cijfers: Array&lt;Double&gt;!
  var wegingen: Array&lt;Double&gt;!
  </code></pre>
  
  <p><strong>6. But how can i delete on of the grades?</strong></p>
  
  <p>I have tried this:</p>
  
  <pre><code>// Override to support editing the table view.
  override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
      if editingStyle == .Delete {
          if cijfers.count != 1 {
              let entityGrade = NSEntityDescription.entityForName("Grade", inManagedObjectContext: mangedobjectcontext)
              let grade = Grade(entity: entityGrade!, insertIntoManagedObjectContext: mangedobjectcontext)
  
              grade.cijfer = cijfers[indexPath.row]
              grade.weging = wegingen[indexPath.row]
              vak.removeGradeObject(grade)
              do{
                  try mangedobjectcontext.save()
              }catch{
                  print("error")
              }
              cijfers.removeAtIndex(indexPath.row)
              wegingen.removeAtIndex(indexPath.row)
              tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
              print(vak.valueForKeyPath("grades.cijfer")?.allObjects)
          }
      }
  }
  </code></pre>
  
  <p>But this doesn't work.</p>
  
  <p><strong>7. And how can i save the vak(subject) to the context when i just change own of the variable?</strong></p>
  
  <p>like this: vak.gemiddelde = newgemiddelde</p>