iosswiftswift3iglistkit

IGListKit insert data to class from Alamofire request


So i have this model

class Event: NSObject {
    var _eventName: String!
    var _venueName : String!
    var _eventImage: String!


    var eventName: String {
        if _eventName == nil {
            _eventName = ""
        }
        return _eventName
    }

    var venueName: String {
        if _venueName == nil {
            _venueName = ""
        }
        return _venueName
    }

    var eventImage: String {
        if _eventImage == nil {
            _eventImage = ""
        }
        return _eventImage
    }

    init(eventsDict: Dictionary<String, AnyObject>) {
        if let venue = eventsDict["venue"] as? Dictionary<String, AnyObject> {
            if let venuname = venue["name"] as? String{
                self._venueName = venuname
            }
        if let eventname = eventsDict["name"] as? String {
            self._eventName = eventname
        }
        if let eventimage = eventsDict["coverPicture"] as? String {
            self._eventImage = eventimage
        }
    }
}

And i make it IGListDiffable with this extension.

extension NSObject: IGListDiffable {

    public func diffIdentifier() -> NSObjectProtocol {
        return self
    }

    public func isEqual(toDiffableObject object: IGListDiffable?) -> Bool {
        return isEqual(object)
    }
}

So when I'm loading data from hardcoded code like this

var entries = [Event]()
func loadFakeEvents() {
        let entries = [
        Event(
            eventName: "Ζωρζ Πιλαλι Και Η Soufra Band Στο AN Groundfloor - Live Stage!",
            venueName: "AN Groundfloor - live stage",
            eventImage: "https://scontent.xx.fbcdn.net/v/t31.0-8/s720x720/15936729_1867160333520142_8855370744955080264_o.jpg?oh=8198bc10a8ea61011d7ec1902b34aa01&oe=593D6BC4"
            ),
        Event(
            date: "2017-02-18T21:30:00+0200",
            name: "Διονύσης Σαββόπουλος at Gazarte I Main Stage 18/02",
            venuename: "Gazarte",
            eventImage: "https://scontent.xx.fbcdn.net/v/t1.0-9/s720x720/16265335_1262826863809003_3636661375515976849_n.jpg?oh=5bb342321a65d33dbc1cc41de266b45e&oe=5907857C"
            )
        ]
        self.entries = entries
    }

The events are loading fine. As they have to.

But when i'm making an alamofire request, of course, it takse some time to load the data and append them to the empty array of events.

This is the function that I have to call the events

    func loadEvents() {

        let parameters: Parameters = [
        "Some" : "Parameters",
        "Some" : "Parameters"
        ]
        Alamofire.request(baseurl, method: .get, parameters: parameters)
            .responseJSON { (responseData) -> Void in
                if((responseData.result.value) != nil) {
                    let result = responseData.result

                    if let dict = result.value as? Dictionary<String, AnyObject>{
                        print(dict) // <-- Check this out
                        if let list = dict["events"] as? [Dictionary<String, AnyObject>] {

                            for obj in list {
                                let event = Event(eventsDict: obj)
                                self.entries.append(event)

                            }
                        }
                    }
                }
        }
  }

So in the above code i have a print, which prints the json.

And in my

extension LocationViewController: IGListAdapterDataSource {
    func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] {
        let items: [IGListDiffable] = loader.entries as [IGListDiffable]
        print(items.count)  // <--- another print of items that should be displayed
        return items
    }
    func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController {
        return NormalSectionController()
    }
    func emptyView(for listAdapter: IGListAdapter) -> UIView? { return nil }
}

Adapter i also print the items that should be displayed. So when i load the fakeEvents function it prints 2 but when i load them with the normal function it prints 0 and then the JSON from the dict var from the previous code.

Normally i would reloadData() of the collection view. But with IGListKit what is the trick of sending the Event Class to the CollectionView? Thanks a lot for your time and i hope i'm not off topic !


Solution

  • Pasting my answer from this same issue on Github in case anyone finds this.

    https://github.com/Instagram/IGListKit/issues/468

    It looks like you're missing a call to self.adapter.performUpdates(animated: true) after the for-loop when appending to the entries dict:

    func loadEvents() {
      // ...
      Alamofire.request(baseurl, method: .get, parameters: parameters)
        .responseJSON { (responseData) -> Void in
    
        if responseData.result.value != nil {
          let result = responseData.result
          if let dict = result.value as? Dictionary<String, AnyObject>{
            if let list = dict["events"] as? [Dictionary<String, AnyObject>] {
              for obj in list {
                let event = Event(eventsDict: obj)
                self.entries.append(event)
              }
              // missing this!
              self.adapter.performUpdates(animated: true)
              // missing that!
            }
          }
        }
      }
    }