ios - Ensuring that FetchedResultsController matches its linked TableView after MOC save -




tldr - frc appears out of sync table view linked to. how can sync?

my view controller (vc) has table view called holestable managed fetched results controller (frc) called fetchedresultscontroller.

when user presses save button on vc, calls ibaction called saveholes. saves data in frc's managed object context tests data rules have been followed. errors caught , message sent on vc displays error user after unwind (not shown here).

i'm discovering frc doesn't have same contents on-screen holestable because function lookforsiproblems doesn't pick errors when called. however, able validate underlying database has received , stored data that's on screen.

subsequent calls vc show saved data , subsequent presses of save button will find error problems.

so, appears frc results out of sync shown in holestable @ time validation.

here's salient code:

fileprivate lazy var fetchedresultscontroller: nsfetchedresultscontroller<hole> = {     // create fetch request     let fetchrequest: nsfetchrequest<hole> = hole.fetchrequest()      // configure fetch request     self.teecolourstring = self.scorecard?.value(forkey: "teecolour") as! string?     fetchrequest.predicate = nspredicate(format: "%k == %@ , %k == %@", "appearson.offeredat.name", self.coursename!, "appearson.teecolour", self.teecolourstring!)      fetchrequest.sortdescriptors = [nssortdescriptor(key: "holenumber", ascending: true)]      // create fetched results controller     let fetchedresultscontroller = nsfetchedresultscontroller(fetchrequest: fetchrequest, managedobjectcontext: self.coredatamanager.mainmanagedobjectcontext, sectionnamekeypath: nil, cachename: nil)      // configure fetched results controller     fetchedresultscontroller.delegate = self      return fetchedresultscontroller }()  @ibaction func saveholes(_ sender: any) {      print("prepare save")      {         try fetchedresultscontroller.managedobjectcontext.save()     }         catch let error nserror {             print("could not save. \(error), \(error.userinfo)")     }      lookforsiproblems(holes: fetchedresultscontroller.fetchedobjects!) }  func lookforsiproblems(holes: [hole]) {     // takes fetched result set of 18 records , looks duplicate or missing si values     // should not possible have duplicate hole numbers, check done see if si number has been seen before and, if so, other hole.      var siexists: [bool] = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]     var sitocheck: int     let maxhole = 18     var currenthole = 0     var proceed = true      while currenthole < maxhole && proceed {          sitocheck = int(holes[currenthole].strokeindex)          if sitocheck == 0 {             // can happen when scorecard has not been completed              messagestopassback = ["incomplete scorecard", "not holes have been given valid stroke index. changes have been saved cannot enter player scores until error has been fixed."]              flagincompleteparforcourse(errorcode: 0)              proceed = false          } else if !siexists[sitocheck-1] {             // no si hole number has yet appeared, set , carry on             siexists[sitocheck-1] = true             currenthole += 1         } else {             // si has been seen              messagestopassback = ["duplicate stroke index", "stroke index \(sitocheck) has been duplicated. changes have been saved cannot enter player scores until error has been fixed."]              flagincompleteparforcourse(errorcode: 1)              proceed = false         }     } } 

edit #1 -

in response comment @agrizzo, full frc delegate methods shown below.

these appear working , carbon copy of delegate code i've used elsewhere in app.

extension scorecardviewcontroller: nsfetchedresultscontrollerdelegate {      func controllerwillchangecontent(_ controller: nsfetchedresultscontroller<nsfetchrequestresult>) {         holestable.beginupdates()     }      func controllerdidchangecontent(_ controller: nsfetchedresultscontroller<nsfetchrequestresult>) {         holestable.endupdates()     }      func controller(_ controller: nsfetchedresultscontroller<nsfetchrequestresult>, didchange anobject: any, @ indexpath: indexpath?, type: nsfetchedresultschangetype, newindexpath: indexpath?) {          switch type {         case .update:             holestable.reloadrows(at: [indexpath!], with: .automatic)         case .insert:             holestable.insertrows(at: [newindexpath!], with: .automatic)         case .delete:             holestable.deleterows(at: [indexpath!], with: .automatic)         case .move:             holestable.moverow(at: indexpath! indexpath, to: newindexpath! indexpath)         }     }      func controller(_ controller: nsfetchedresultscontroller<nsfetchrequestresult>, didchange sectioninfo: nsfetchedresultssectioninfo, atsectionindex sectionindex: int, type: nsfetchedresultschangetype) {          switch type {         case .insert:             holestable.insertsections(nsindexset(index: sectionindex) indexset, with: .fade)         case .delete:             holestable.deletesections(nsindexset(index: sectionindex) indexset, with: .fade)         case .move:             break         case .update:             break         }     }  } 

edit #2:

to see if frc updating on each edit, added call lookforsiproblems frc delegate methods thus:

func controller(_ controller: nsfetchedresultscontroller<nsfetchrequestresult>, didchange anobject: any, @ indexpath: indexpath?, type: nsfetchedresultschangetype, newindexpath: indexpath?) {      switch type {     case .update:         holestable.reloadrows(at: [indexpath!], with: .automatic)         lookforsiproblems(fetchedresultscontroller.fetchedobjects!)     case .insert:         holestable.insertrows(at: [newindexpath!], with: .automatic)     case .delete:         holestable.deleterows(at: [indexpath!], with: .automatic)     case .move:         holestable.moverow(at: indexpath! indexpath, to: newindexpath! indexpath)     } } 

and result frc is showing values in sync table. went on isolate think problem is. if edit fetched object in table hit save button, frc in lookforsiproblems seems using 'dirty' data. however, if edit object in table click on item in table, say, frc in lookforsiproblems uses 'fresh' data.

not sure means.





wiki

Comments

Popular posts from this blog

Asterisk AGI Python Script to Dialplan does not work -

python - Read npy file directly from S3 StreamingBody -

kotlin - Out-projected type in generic interface prohibits the use of metod with generic parameter -