Instagram / IGListKit

A data-driven UICollectionView framework for building fast and flexible lists.
https://instagram.github.io/IGListKit/
MIT License
12.87k stars 1.54k forks source link

Where do you put exactly your networking code when using IGLikstKit? #551

Closed Ricardo1980 closed 7 years ago

Ricardo1980 commented 7 years ago

New issue checklist

General information

Hello,

I would like to know your opinion about this:

Lets say one of your cells is a toolbar with a Like button, that sends a network request when pressed (basically like Facebook, but without optimistic UI, so I wait for response) You reuse that cell in several section controllers, some of them, not all. My question is: Where do you write that networking logic? I guess writing this in the section controller is not a good idea, because in that case, then we are repeating a lot of logic that is different. If we are using MVC or MVVM or similar, does this mean we have to use delegates to connect the cell, passing through the section controller, collection view and view controller, to use something like NetworkServiceProvider? And when we have the response, then the opposite path.

Just wanted to know your suggestions about how you architect your app for this. Thanks a lot.

heumn commented 7 years ago

This is a really good question and a well discussed topic. Straight to the point @rnystrom has begun making a nice weather app using IGListKit over here: https://github.com/rnystrom/SimpleWeather

Maybe something like that is what you would like to dig into? It shows a nice and simple separation of concerns and where one could put networking logic. I learned a lot about IGListKit by reading his code. Altough @rnystrom probably put a bit too much network knowledge in his VC for my personal taste, he does something simple and it works great. And simple is always the best starting point to build from. Do not overengineer.

And you are absolutely right. Putting network logic directly in a Section Controller / View Controller is something you should avoid.

"If we are using MVC or MVVM or similar, does this mean we have to use delegates to connect the cell, passing through the section controller, collection view and view controller, to use something like NetworkServiceProvider?"

Not entirely sure I understood your suggestion here but yes. Using something like a NetworkServiceProvider sounds like a good idea 👌

Personally I create the top level models (section models) in the ViewModel for my ViewController. For example:

I have a FeedViewController class that owns a ViewModel that serves the section model for each section in the IGListViewCollectionView

final class FeedViewController: UIViewController {

    fileprivate let viewModel = FeedViewModel()

    ...
}
final class FeedViewModel: NSObject {
    var sections = [IGListDiffable]()

    ...
}

I serve sections like this to the adapter

extension FeedViewController: IGListAdapterDataSource {

    func objects(for _: IGListAdapter) -> [IGListDiffable] {
        return viewModel.sections
    }

    ...
}

This ViewModel knows about the service that it uses to fetch data and then create the sections:

fileprivate func buildSections() {
       self.sections = sectionList.map({
            switch Section.SectionType(rawValue: $0.template) ?? .standard {
            case .condensed: return CondensedSection(section: $0)
            case .mainplug: return MainSection(section: $0)
            case .standard: return StandarSection(section: $0)
            case .poster: return PosterSection(section: $0)
            }
        })

        if isUpdating {
            sections.insert(SpinnerSection(), at: 0)
        }
    }

This has a few benefits that I value highly in my projects and most importantly the View Controller can focus on view-logic and knows nothing about the logic of building sections nor who what or where the data comes from.

To give you another suggestion I would read more about the different options I think this medium post summarizes the different options well https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52#.iab7e9hh2

Do not be overvelmed by all the names and architectures. There are no silver bullets. Everything has drawbacks and there is no such thing as a perfect architecture. The fact that you are asking these questions is a great start.

Sorry for the long post, but I hope I at least answered some parts of your question.

Make everything as simple as possible, but not simpler — Albert Einstein

Ricardo1980 commented 7 years ago

Thanks a lot for your response. You are not going to believe this, but I already have FeedViewController, FeedViewModel and buildSections in my code. Are you in London? ;)

heumn commented 7 years ago

Thanks a lot for your response.

My pleasure!

You are not going to believe this, but I already have FeedViewController, FeedViewModel and buildSections in my code. Are you in London? ;)

Hehe.. No I am located in Oslo, Norway :)

jessesquires commented 7 years ago

Thanks @heumn ! 💯 🥇