ios - Using UICollectionView with CoreData and NSFetchedResultsController -


i started project exploring swift little bit. want implement collection view using nsfetchedresultscontroller data out of coredata database. wanted use example https://github.com/ashfurrow/uicollectionview-nsfetchedresultscontroller , implement similar in swift. don't need of move events implemented following:

first of created class save changes made:

class changeitem{     var index:nsindexpath     var type:nsfetchedresultschangetype      init(index: nsindexpath, type: nsfetchedresultschangetype){         self.index = index         self.type = type     } } 

within collection view controller use 2 arrays save changes temporarily

var sectionchanges:[changeitem] = [] var objectchanges:[changeitem] = [] 

then wait fetchedresultscontroller change after changes on coredata database made

func controller(controller: nsfetchedresultscontroller, didchangeobject anobject: anyobject, atindexpath indexpath: nsindexpath?,forchangetype type: nsfetchedresultschangetype, newindexpath: nsindexpath?) {     var item:changeitem?     if(type == nsfetchedresultschangetype.insert){         item = changeitem(index: newindexpath!, type: type)     }else if(type == nsfetchedresultschangetype.delete){         item = changeitem(index: indexpath!, type: type)     }else if(type == nsfetchedresultschangetype.update){         item = changeitem(index: indexpath!, type: type)     }     if(item != nil){         self.objectchanges.append(item!)     } }  func controller(controller: nsfetchedresultscontroller, didchangesection sectioninfo: nsfetchedresultssectioninfo, atindex sectionindex: int, forchangetype type: nsfetchedresultschangetype) {     var item:changeitem?       if(type == nsfetchedresultschangetype.insert || type == nsfetchedresultschangetype.delete || type == nsfetchedresultschangetype.update){         item = changeitem(index: nsindexpath(forrow: 0, insection: sectionindex), type: type)     }     if(item != nil){         self.sectionchanges.append(item!)     } } 

after changes applied fetchedresultscontroller perform didchangecontent method

func controllerdidchangecontent(controller: nsfetchedresultscontroller) {     println("something happened")      self.collectionview!.performbatchupdates({ () -> void in         while(self.sectionchanges.count > 0 || self.objectchanges.count > 0){             self.insertsections()             self.insertitems()             self.updateitems()             let delips = self.deletesections()             self.deleteitems(delips)         }          }, completion: { (done) -> void in             if(done){                 println("done")                 self.collectionview.reloaddata()             }else{                 println("not done")                 self.collectionview.reloaddata()             }             if(self.fetchedresultscontroller.sections != nil && self.fetchedresultscontroller.sections?.count > 0){                 println("number of items in first section \(self.fetchedresultscontroller.sections![0].count)")             }     })       self.deselectall()     self.collectionview.reloaddata()     if(self.fetchedresultscontroller.sections != nil && self.fetchedresultscontroller.sections!.count > 0){          in 1 ..< self.fetchedresultscontroller.sections!.count{             if(self.fetchedresultscontroller.sections!.count > 0){                 println(self.fetchedresultscontroller.sections![i].numberofobjects )             }         }     }  } 

which again calls following methods

private func deletesections()->nsindexset{     var deletes = self.sectionchanges.filter({ (item) -> bool in         if(item.type == nsfetchedresultschangetype.delete){              let index = (self.sectionchanges nsarray).indexofobject(item)             self.sectionchanges.removeatindex(index)             return true         }           return false     }) [changeitem]     var indexset:nsmutableindexset = nsmutableindexset()     del in deletes{          indexset.addindex(del.index.section)     }     if(indexset.count > 0 && self.collectionview.numberofsections() > 0){         self.collectionview.deletesections(indexset)     }     return indexset }  private func insertsections(){     var inserts = self.sectionchanges.filter({ (item) -> bool in         if(item.type == nsfetchedresultschangetype.insert){             let index = (self.sectionchanges nsarray).indexofobject(item)             self.sectionchanges.removeatindex(index)             return true         }         return false     }) [changeitem]     var indexset:nsmutableindexset = nsmutableindexset()     ins in inserts{         indexset.addindex(ins.index.section)     }     if(indexset.count > 0){         println("adding \(indexset.count) section")         println(indexset)          self.collectionview.insertsections(indexset)         self.collectionview.reloadsections(indexset)     } }  private func deleteitems(deletedsections:nsindexset?){     var deletes = self.objectchanges.filter({ (item) -> bool in         if(item.type == nsfetchedresultschangetype.delete){             let index = (self.objectchanges nsarray).indexofobject(item)             self.objectchanges.removeatindex(index)             return true         }     return false     }) [changeitem]     var indexpaths:[nsindexpath] = []      del in deletes{         if(del.index.section < self.fetchedresultscontroller.sections?.count){              if(deletedsections == nil || deletedsections!.containsindex(del.index.section)){                 indexpaths.append(del.index)             }         }     }     /*indexpaths = indexpaths.sorted({ (a, b) -> bool in         if(a.section >= b.section && a.row >= b.row){             return true         }         return false     })     println(indexpaths)*/     //self.collectionview.numberofitemsinsection(0)     if(indexpaths.count > 0){         println("deleting \(indexpaths.count) items")         self.collectionview.deleteitemsatindexpaths(indexpaths)     }   } private func updateitems(){      var updates = self.objectchanges.filter({ (item) -> bool in         if(item.type == nsfetchedresultschangetype.update){             let index = (self.objectchanges nsarray).indexofobject(item)             self.objectchanges.removeatindex(index)             return true         }         return false     }) [changeitem]     var indexpaths:[nsindexpath] = []     update in updates{         indexpaths.append(update.index)     }     if(indexpaths.count > 0 ){         println("did update on \(indexpaths.count) items")         self.collectionview.reloaditemsatindexpaths(indexpaths)     }  } private func insertitems(){     var inserts = self.objectchanges.filter({ (item) -> bool in         if(item.type == nsfetchedresultschangetype.insert){             let index = (self.objectchanges nsarray).indexofobject(item)             self.objectchanges.removeatindex(index)             return true         }         return false     }) [changeitem]     var indexpaths:[nsindexpath] = []     ins in inserts{         indexpaths.append(ins.index)     }     if(indexpaths.count > 0 && self.numberofsectionsincollectionview(self.collectionview) > 0){          println("adding \(indexpaths.count) items collection view \(self.collectionview.numberofitemsinsection(0))")         self.collectionview.insertitemsatindexpaths(indexpaths)         println("did add items")     }  } 

deleting multiple items , sections @ time works fine (by now), inserting section not work. can see implemented output within insertsections method. number of new sections in test scenario 1 , right nsindexset 1 item:(0). in insertitems method try call numberofobjects on section 0 , following error

*** assertion failure in -[uicollectionviewdata numberofitemsinsection:], /sourcecache/uikit_sim/uikit3347.44/uicollectionviewdata.m:5942015-06-19:00:53:01.966 grocli[42533:1547866] coredata: error: serious application error.  exception caught delegate of nsfetchedresultscontroller during call -controllerdidchangecontent:.  request number of items in section 0 when there 0 sections in collection view userinfo (null) 

thanks in advance reading long article , helping me out!

sounds issue had while ago, when using objective c.

check out

uicollectionview assertion failure

i had work around frc work collection view.

seems found same git me, here fix solves collection view issue.

https://github.com/ashfurrow/uicollectionview-nsfetchedresultscontroller/issues/13


Comments

Popular posts from this blog

powershell Start-Process exit code -1073741502 when used with Credential from a windows service environment -

twig - Using Twigbridge in a Laravel 5.1 Package -

c# - LINQ join Entities from HashSet's, Join vs Dictionary vs HashSet performance -