7 Replies
      Latest reply on Jul 16, 2019 12:47 PM by wlionel
      wlionel Level 1 Level 1 (0 points)

        Hello all:

         

        I am looking for a way to save a pickerView selection to CoreData with no success so far. I want to save the  row numerical value from 0 - 6, depending on the selected value. Below is the code I am trying but it is not working. It is saving random values not the one selected:

         

          @IBAction func saveRating(_ sender: Any) {        

                    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {

                        return

                    }

                    let managedContext = appDelegate.persistentContainer.viewContext

                    let entity = NSEntityDescription.entity(forEntityName: "DecisionComponents", in: managedContext)!

                    let component = NSManagedObject(entity: entity, insertInto: managedContext)

              

                    let whyNowTitles = ["very poor reason","poor reason","passable reason", "good reason" , "very good reason", "excellent reason"]

          

                func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

                    selectedRating = whyNowTitles[row]

                    textLabel.text = selectedRating

                    let stored = row

                    print (stored)

                    print(selectedRating!)

                }

                     for (stored) in whyNowTitles {

                     component.setValue(stored.self, forKeyPath: "components")       

                    do {

                        try managedContext.save()

                     decisions.append(component)

                        print ("SAVED")

                    } catch let error as NSError {

                        print("Could not save. \(error), \(error.userInfo)")

                    }

            

                }

          

            }

        • Re: How to save selected pickerView value to CoreData
          Claude31 Level 8 Level 8 (6,585 points)

          You have included

                  func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { }

           

          in the IBAction. So it is not visible as a delegate func.

           

          Take it out at the top level, it should work better (unless there are other errors). Take whyNowTitles out as well

           

           

          let whyNowTitles = ["very poor reason","poor reason","passable reason", "good reason" , "very good reason", "excellent reason"]
          
          func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
                      selectedRating = whyNowTitles[row]
                      textLabel.text = selectedRating
                      let stored = row
                      print (stored)
                      print(selectedRating!)
          }
          
            @IBAction func saveRating(_ sender: Any) {   
                      guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
                          return
                      }
                      let managedContext = appDelegate.persistentContainer.viewContext
                      let entity = NSEntityDescription.entity(forEntityName: "DecisionComponents", in: managedContext)!
                      let component = NSManagedObject(entity: entity, insertInto: managedContext)
          
                       for (stored) in whyNowTitles {
                       component.setValue(stored.self, forKeyPath: "components")  
                      do {
                          try managedContext.save()
                       decisions.append(component)
                          print ("SAVED")
                      } catch let error as NSError {
                          print("Could not save. \(error), \(error.userInfo)")
                      }
          
                  }
          
              }
            • Re: How to save selected pickerView value to CoreData
              wlionel Level 1 Level 1 (0 points)

              Hello Calude31:

               

              My main problem is how to get the value of the selected row so I cam save it to the managedContext.

              I am trying to get the value to UserDefaults then to the Managed Context but without success.

               

              At the pickerView i see the correct number of the selected row:

               

                func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

                      selectedRating = pickerTitles[row]

                      UserDefaults.standard.set(row, forKey: "pickerViewRow")

                      textLabel.text = selectedRating

                      print (selectedRating!)

                      print (row)

                  }

              In pickerView  print (row) the value is 5 correct.

               

               

              But in the below code:

               

              guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {

                          return

                      }

                  

                      let managedContext = appDelegate.persistentContainer.viewContext

                      let entity = NSEntityDescription.entity(forEntityName: "DecisionComponents", in: managedContext)!

                      let component = NSManagedObject(entity: entity, insertInto: managedContext)

                  

                          UserDefaults.standard.set(row, forKey: "pickerViewRow")

                          component.setValue(row.self, forKeyPath: "components")

                          print (row)

                          print("User Selected \(row)")

                

                      do {

                          try managedContext.save()

                          decisions.append(component)

                      

              The print row value is 0 wrong.

               

              How do i get the pickerView row into the managedContext????

                • Re: How to save selected pickerView value to CoreData
                  Claude31 Level 8 Level 8 (6,585 points)

                  Where is this code located ?

                   

                  guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
                              return
                          }
                      
                          let managedContext = appDelegate.persistentContainer.viewContext
                          let entity = NSEntityDescription.entity(forEntityName: "DecisionComponents", in: managedContext)!
                          let component = NSManagedObject(entity: entity, insertInto: managedContext)
                      
                              UserDefaults.standard.set(row, forKey: "pickerViewRow")
                              component.setValue(row.self, forKeyPath: "components")
                              print (row)
                              print("User Selected \(row)")
                    
                          do {
                              try managedContext.save()
                              decisions.append(component)

                   

                   

                  You set the UserDefaults with a value row.

                  Where is row defined in this part of code ?

                  Probably it is 0.

                   

                  What are you trying to achieve here ?

                  I would understand you try to read not set the value.

                  To do so:

                          row = defaults.integer(forKey: "pickerViewRow")          // if row is a var defined as Int somewhere
                    • Re: How to save selected pickerView value to CoreData
                      wlionel Level 1 Level 1 (0 points)

                      Here is the full code:

                       

                      import UIKit

                      import CoreData

                       

                      class RatingGLViewController: UIViewController, UITextViewDelegate {

                          @IBOutlet weak var tableView: UITableView!

                          @IBOutlet weak var pickerView: UIPickerView!

                          @IBOutlet weak var textLabel: UILabel!

                       

                          let row = UserDefaults.standard.integer(forKey: "pickerViewRow")

                          var decisions: [NSManagedObject] = []

                          var selectedRating: String?

                       

                          override func viewDidLoad() {

                              super.viewDidLoad()

                             self.pickerView.delegate = self

                             self.pickerView.dataSource = self

                           

                         tableView.register(UITableViewCell.self,  forCellReuseIdentifier: "cell")

                         }

                         override func touchesBegan(_ touches: Set<UITouch>,

                                                     with event: UIEvent?) {

                              self.view.endEditing(true)

                          }

                          override func viewWillAppear (_ animated: Bool) {

                              super.viewWillAppear(animated) 

                          }

                          override func didReceiveMemoryWarning()

                          {super.didReceiveMemoryWarning()

                              // Dispose of any resources that can be recreated.

                          }

                          @IBAction func saveRating(_ sender: Any){

                       

                              guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {

                                  return

                              }

                       

                      // pickerView components

                              _ = ["insignificant", "little significance", "somewhat significant", "significant", "highly significant", "very highly significant"]

                       

                             //  Saving pickerView row

                       

                              let managedContext = appDelegate.persistentContainer.viewContext

                              let entity = NSEntityDescription.entity(forEntityName: "DecisionComponents", in: managedContext)!

                              let component = NSManagedObject(entity: entity, insertInto: managedContext)

                           

                                  UserDefaults.standard.set(row, forKey: "pickerViewRow")

                                  component.setValue(row.self, forKeyPath: "components")

                                  print (row) // Printing 0 instead of the selected row here

                                  print("User Selected \(row)") // printing  0

                              do {

                                  try managedContext.save()

                                  decisions.append(component)

                               

                                  print ("SAVED")

                               

                              } catch let error as NSError {

                                  print("Could not save. \(error), \(error.userInfo)")

                              }

                          }

                       

                      }

                       

                      extension RatingGLViewController: UITableViewDataSource {

                          func tableView(_ tableView: UITableView,

                                         numberOfRowsInSection section: Int) -> Int {

                              return decisions.count

                          }

                          func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

                           

                              let component = decisions[indexPath.row]

                              let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

                              cell.textLabel?.text = component.value(forKeyPath: "component") as? String

                              return cell

                          }

                          func tableView(_tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {

                              return true

                          }

                      }

                       

                      let pickerTitles = ["insignificant", "little significance", "somewhat significant", "significant", "highly significant", "very highly significant"]

                       

                      extension RatingGLViewController: UIPickerViewDataSource, UIPickerViewDelegate {

                          func numberOfComponents(in pickerView: UIPickerView) -> Int {

                              return 1

                          }

                          func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

                           //   print ("TEST THREE")

                              return  pickerTitles.count

                          }

                          func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?{

                              return pickerTitles[row]

                          }

                          func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

                              selectedRating = pickerTitles[row]

                              UserDefaults.standard.set(row, forKey: "pickerViewRow")

                              textLabel.text = selectedRating

                              print (selectedRating!)

                              print (row)   // printing corrected of "selectedRating"

                          }

                      }

                        • Re: How to save selected pickerView value to CoreData
                          Claude31 Level 8 Level 8 (6,585 points)

                          You define row as a coinstant, not as a value you read from picker

                           

                              let row = UserDefaults.standard.integer(forKey: "pickerViewRow")

                           

                          If you print it in viewDidLoad, row is probably 0

                          print(#function, row)

                          And it is not changed (row ib picker(didSelectRow) is a local var

                           

                          One way to correct it is to declare row as a var

                               (note that it would be less misleading to call it pickedRow for instance, to see the difference with row in picker delegate)

                           

                              var row = UserDefaults.standard.integer(forKey: "pickerViewRow")

                           

                          So, in saveRating, row (in fact self.row) has now the correct value:

                           

                              @IBAction func saveRating(_ sender: Any){
                          
                                  guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {  return  }
                          
                                    // pickerView components
                                  _ = ["insignificant", "little significance", "somewhat significant", "significant", "highly significant", "very highly significant"]
                          
                                 //  Saving pickerView row
                               // IN FACT, you save self.row that was updated with picker row
                          
                                    let managedContext = appDelegate.persistentContainer.viewContext
                                    let entity = NSEntityDescription.entity(forEntityName: "DecisionComponents", in: managedContext)!
                                    let component = NSManagedObject(entity: entity, insertInto: managedContext)
                              
                                      UserDefaults.standard.set(self.row, forKey: "pickerViewRow")          // row is self.row, which has been updated in picker delegate
                                      component.setValue(row.self, forKeyPath: "components")
                                      print (row) // Printing 0 instead of the selected row here
                                      print("User Selected \(row)") // printing  0
                                  do {
                                      try managedContext.save()
                                      decisions.append(component)
                                  
                                      print ("SAVED")
                                  
                                  } catch let error as NSError {
                                      print("Could not save. \(error), \(error.userInfo)")
                                  }
                              }
                          
                          }

                          In

                          extension RatingGLViewController: UIPickerViewDataSource, UIPickerViewDelegate {

                           

                          change to update self.row

                           

                              func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
                                  selectedRating = pickerTitles[row]
                                  UserDefaults.standard.set(row, forKey: "pickerViewRow")
                                  self.row = row       // ADD THIS    // That is the pickerRow defined as a var
                                  textLabel.text = selectedRating
                                  print (selectedRating!)
                                  print (row)   // printing corrected of "selectedRating"
                              }
                            • Re: How to save selected pickerView value to CoreData
                              Claude31 Level 8 Level 8 (6,585 points)

                              ANother point to explain the problem.

                               

                              In picker, you saved the userDefault with the correct row value

                               

                                  func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
                                      selectedRating = pickerTitles[row]
                                      UserDefaults.standard.set(row, forKey: "pickerViewRow")
                                      textLabel.text = selectedRating
                                      print (selectedRating!)
                                      print (row)   // printing corrected of "selectedRating"
                                  }

                               

                               

                              But in saveRating, you saved it again with the row constant value that you created when creating the class instance:

                              this value is 0 and it replaces the value you have just saved in picker delegate !

                               

                                  @IBAction func saveRating(_ sender: Any){
                              
                                      guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {  return  }
                              
                              // …………    
                                          UserDefaults.standard.set(row, forKey: "pickerViewRow")
                                          component.setValue(row.self, forKeyPath: "components")
                                          print (row) // Printing 0 instead of the selected row here
                                          print("User Selected \(row)") // printing  0

                               

                               

                              With the changes I propose, that will not occur anymore.