4 Replies
      Latest reply on May 24, 2020 1:42 PM by wlionel
      wlionel Level 1 Level 1 (0 points)

        Hello:

         

        I have successfully read data from a plist and want to save that data to CoreData. From the code below I am not getting errors but it is not saving the plist data.

         

        Please suggest what I am missing:

         

        func preloadScq() {
             print("Call to preload Data Starts Now")
             let preloadedDataKey = "didPreloadData"
             UserDefaults.standard.removeObject(forKey: preloadedDataKey)
             let userDefaults = UserDefaults.standard
             if userDefaults.bool(forKey: preloadedDataKey) == false {
                 guard let plistUrl = Bundle.main.url(forResource: "SCQ", withExtension:"plist") else {
                     return
                 }
                let backgroundContext = persistentContainer.newBackgroundContext()
              
                persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
             
                backgroundContext.perform {
                     let scqObjects = NSEntityDescription.insertNewObject(forEntityName: "SCQ", into: backgroundContext)
                    if let arrayContents = NSArray(contentsOf: plistUrl) as? [String] {
                   
                       
                        do {
                           
                        let plistData = try Data(contentsOf: plistUrl)
                        let scqList = try PropertyListDecoder().decode([Scq].self, from: plistData)
        
                        for scqName in scqList {
                            let scqObject = SCQ(context: backgroundContext)
                            scqObject.answer = "answer" // the first object in the plist
                            print ("Answer is \(scqObject)") // This doesn't print anything
                        }
                       try backgroundContext.save()
                        } catch {
                           
                            print(error)
                            print ("Your Record is Saved")
                    }
                }
            }
          //
        • Re: How to save plist data to CoreData
          Claude31 Level 8 Level 8 (9,215 points)

          Coulkd you show all the print you get when you run ?

           

          Notably to see if you return at line 08.

            • Re: How to save plist data to CoreData
              wlionel Level 1 Level 1 (0 points)

              Hello Claude31:

               

              I edited the code as below and am getting a debug list as below:

               

              func preloadScq() {
                             let backgroundContext = persistentContainer.newBackgroundContext()
                               persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
                              _ = NSEntityDescription.entity(forEntityName: "SCQ", in: backgroundContext)!
                     
                   print("Call to preload Data Starts Now")
                   let preloadedDataKey = "didPreloadData"
                   UserDefaults.standard.removeObject(forKey: preloadedDataKey)
                   let userDefaults = UserDefaults.standard
                   if userDefaults.bool(forKey: preloadedDataKey) == false {
                          guard let plistUrl = Bundle.main.url(forResource: "SCQ", withExtension:"plist") else {
                             return
                         }
                         do {
                              let plistData = try Data(contentsOf: plistUrl)
                              let scqList = try PropertyListDecoder().decode([Scq].self, from: plistData)
                              let scqObjects = NSEntityDescription.insertNewObject(forEntityName: "SCQ", into: backgroundContext)
                             print(scqList)
                          for scqName in scqList {
                              let scqObject = SCQ(context: backgroundContext)
                //              print(scqName)
                              scqObject.answer = ("answer")
                              print(scqName)
                          }
                              try backgroundContext.save()
                              print("SAVED")
              //                 userDefaults.set (true, forKey: preLoadedDataKey)
                            
                        
                       } catch {
                             print(error)
                          }
                      }
                  }

              I get a print of the plist contents:

              [ScorCentMasterReview.AppDelegate.Scq(answer: "1", distractor1: "R", distractor2: "Wr", distractor3: "DK", distractor4: "not here", distractor5: "not here", grade: "2", id: "403", qid: "1", question: "If the word is spelled correctly choose R. If it is not spelled correctly choose Wr. If you don’t know choose DK. The noise was TERRIBLE.", qValue: "1000", skill: "Spell Terrible Correctly", subject: "ELA", topic: "SPELLING")

               

              But The object that is saved is not the value for "answer" but the word "answer":

              CoreData: sql: INSERT INTO ZSCQ(Z_PK, Z_ENT, Z_OPT, ZANSWER, ZDIFFICULTYLEVEL, ZDISTRACTOR1, ZDISTRACTOR2, ZDISTRACTOR3, ZDISTRACTOR4, ZDISTRACTOR5, ZGRADE, ZID, ZQVALUE, ZQID, ZQUESTION, ZSKILL, ZSUBJECT, ZTOPIC) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

              CoreData: details: SQLite bind[0] = (int64)2545

              CoreData: details: SQLite bind[1] = (int64)7

              CoreData: details: SQLite bind[2] = (int64)1

              CoreData: details: SQLite bind[3] = "answer"

                • Re: How to save plist data to CoreData
                  Claude31 Level 8 Level 8 (9,215 points)

                  Line 22, why put the string into parenthesis ?

                   

                  Note: when you print for log, it's a good practice to add a label, to know exactly what you are getting:

                                 print("scqList", scqList)
                                 print("scqName", scqName)

                   

                   

                  And please show the complete log (including the initial "Call to preload Data Starts Now"

                    • Re: How to save plist data to CoreData
                      wlionel Level 1 Level 1 (0 points)

                      Hello Calude31:

                       

                      After a week of struggle with your and 00per's suggestions, I finallg figured out the solution and as usual it was really a simple fix:

                       

                      func preloadScq() {
                          let backgroundContext = persistentContainer.newBackgroundContext()
                              persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
                             _ = NSEntityDescription.entity(forEntityName: "SCQ", in: backgroundContext)!
                           print("Call to preload Data Starts Now")
                           let preloadedDataKey = "didPreloadData"
                           UserDefaults.standard.removeObject(forKey: preloadedDataKey)
                           let userDefaults = UserDefaults.standard
                           if userDefaults.bool(forKey: preloadedDataKey) == false {
                               guard let plistUrl = Bundle.main.url(forResource: "SCQ", withExtension:"plist") else {
                                   return
                               }
                               do {
                                  typealias Settings = [Scq]
                                  var settings: Scq?
                                   let plistData = try Data(contentsOf: plistUrl)
                                   let scqList = try PropertyListDecoder().decode([Scq].self, from: plistData)
                                   print(scqList)
                                  for items in scqList {
                                      print("These are the \(items)")
                                      let entity = NSEntityDescription.entity(forEntityName: "SCQ", in: backgroundContext)!
                                      let newEntity = NSManagedObject(entity: entity, insertInto: backgroundContext)
                                      newEntity.setValue(items.answer, forKeyPath: ("answer" as? String)!)//This line did the trick
                                      print ("This is the new entity \(items.answer)")
                                      try backgroundContext.save()
                                          print("SAVED")
                                    }
                               } catch {
                                   print(error)
                               }
                       
                             
                           }

                       

                      Thanks.