# Best Practices and FAQ Reference

# Best Practices and FAQs

This guide provides notes and details on best practices in using `IGListKit`, general tips, and answers to FAQs.

## Best Practices

- We recommend adding an assert to check `-isKindOfClass:` on the object you receive in `-didUpdateToObject:` in your section controllers. This makes it easy to track down easily-overlooked mistakes in your `IGListAdapaterDataSource` implementation. If this assert is ever hit, that means `IGListKit` has sent your section controller the incorrect type of object. This would only happen if your objects provide non-unique diff identifiers.

    // Objective-C
    - (void)didUpdateToObject:(id)object {
        NSParameterAssert([object isKindOfClass:[MyModelClass class]]);
        _myModel = object;
    }

    // Swift
    func didUpdate(to object: Any) {
        precondition(object is MyModelClass)
        myModel = object as! MyModelClass
    }

- Make sure your `-diffIdentifier` implementation returns a unique identifier for each object.

- We highly recommend using single-item sections when possible. That is, each section controller manages a single model (which may have one or multiple cells). This gives you the greatest amount of flexibility, modularity, and re-use for your components.

## Frequently asked questions

#### I upgraded IGListKit and now everything is broken!

Check out our migration guide to make upgrading easier.

#### How do you implement separators between cells?

See discussion in #329

#### How do I fix the error `Could not build Objective-C module 'IGListKit'`?

See discussion in #316

#### The documentation and examples have `<X>` feature or changes, but I don’t have it in my version. Why?

This feature is on the `main` branch only and hasn’t been officially tagged and released. If you need to, you can install from the `main` branch.

#### Does `IGListKit` work with…?

- Core Data (Working with Core Data Guide)
- AsyncDisplayKit (AsyncDisplayKit/#2942)
- ComponentKit (ocrickard/IGListKit-ComponentKit)
- RxSwift (RxSwiftCommunity/RxIGListKit)
- React Native
- Reactive Cocoa

Yes.

#### Does `IGListKit` work with `UITableView`?

No, but you can install the diffing subspec via CocoaPods.

#### What’s the purpose of `IGListCollectionView`?

Historically, we used this subclass to gain compile-time safety to prevent disallowed methods from being called on `UICollectionView`, because `IGListKit` handles model and view updates. However, it has since been removed. See discussion at #409.

#### How can I manage cell selection and deselection?

See discussion at #184.

#### I have a huge data set and `-performUpdatesAnimated: completion:` is super slow. What do I do?

If you have multiple thousands of items and you cannot batch them in, you’ll see performance issues with `-performUpdatesAnimated: completion:`. The real bottleneck behind the scenes here is `UICollectionView` attempting to insert so many cells at once. Instead, call `-reloadDataWithCompletion:` when you first load data. Behind the scenes, this method does not do any diffing and simply calls `-reloadData` on `UICollectionView`. For subsequent updates, you can then use `-performUpdatesAnimated: completion:`.

#### How do I use IGListKit and estimated cell sizes with Auto Layout?

This should work in theory, and we have an example section controller, but the estimated-size API in `UICollectionViewFlowLayout` has changed dramatically over different iOS versions, making first-class support in IGListKit difficult. We don’t use estimated cell sizes or Auto Layout in Instagram and cannot commit to fully supporting it.

See #516 for a master list of all known issues. We very much welcome contribution to fixing this!

#### Is creating a “wrapper” model just for IGListKit ok?

Yes! We create models that act as a grab-bag for other models, specifically for use in section controllers. Things like:

    class WeatherSectionModel {
      let location: Location
      let forecast: Forecast
      let conditions: Conditions
    }

Just don’t forget to make your models diffable using the data in the contained models:

    extension WeatherSectionModel: ListDiffable {
      func diffIdentifier() -> NSObjectProtocol {
        return location.identifier
      }

      func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
        guard self !== object else { return true }
        guard let object = object as? WeatherSectionModel else { return false }
        return location == object.location && forecast == object.forecast && conditions == object.conditions
      }
    }

#### What if I want to make my Swift structs diffable?

Give this box a try.

#### I want to deliver messages to certain section controllers, how do I do that?

We recommend using dependency injection and announcing changes, demonstrated in our example.

#### Should I reuse my section controllers between models?

No! `IGListKit` is designed to have a 1:1 instance mapping between objects and section controllers. `IGListKit` does not reuse section controllers, and if you do unintended behaviors will occur.

`IGListKit` does still use `UICollectionView`‘s cell reuse, so you shouldn’t be concerned about performance.

#### Why does `UICollectionViewFlowLayout` put everything in a new row?

`UICollectionViewFlowLayout` has its limitations, and it’s not well designed to support sections on the same “line”. Instead you should use `IGListCollectionViewLayout`.

#### What if I just want a section controller and don’t need the object?

Feel free to use a static string or number as your model. You can use this object as a “key” to find your section controller. Take a look at our example of this.

#### How do I make my cells diff and animate?

Use `IGListBindingSectionController` to automatically diff and animate your cells.

#### How can I power and update the number of items in a section controller with a dynamic array?

We recommend creating a model that owns an array to the items that power `numberOfItems`. Checkout our Post example that has dynamic comment cells. Just be sure to check when your array changes:

    class Forecast: ListDiffable {
      let day: Date
      let hourly: [HourlyForecast]

      func diffIdentifier() -> NSObjectProtocol {
        return day
      }

      func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
        guard self !== object else { return true }
        guard let object = object as? Forecast else { return false }
        return hourly == object.hourly // compare elements in the arrays
      }
    }

© 2024 Instagram. All rights reserved. (Last updated: 2024-05-13)

Generated by jazzy ♪♫ v0.15.0, a Realm project.