Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Diffable Data Source by Sudeep Kini

Diffable Data Source by Sudeep Kini

Swift Bangalore meet up - Chapter #18

Eeb061c8b2816b771920da1b3e7904a3?s=128

Swift India

October 19, 2019
Tweet

Transcript

  1. Diffable Data sources Sudeep Pratap kini / Dunzo @sudeepkini

  2. • Data source and current api • What new ?

    • Demo • Things to consider Index
  3. Data source A class that configures the Table/Collection view 1.

    Number of section, Number of items 2. Cell For Items/Row 3. Size For Item (optional after automatic dimensions) The Table View/Collection View handles the presentation on screen.
  4. func numberOfSections(in collectionView: UICollectionView) -> Int { return models.count }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return models[section].count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for:indexPath) // configure cell return cell } UICollectionViewDataSource
  5. Advantages • Simple and Straightforward api ◦ Mapping data to

    Cell UI • Rapid Iteration • Flexible ◦ Freedom to choose how to store the backing data ◦ Decoupled from rest of the view layout logic ◦ Support for Multiple sections
  6. The modern apps world • Dynamically changing data set •

    Changed by ◦ User Interactions ◦ Web Services and sockets ◦ Business logic/ databases • Refresh TableViews / CollectionViews.
  7. Controller UI Layer Data set Change Reload UI Number of

    sections Number of Items Configure cell
  8. Use cases Examples Search Suggestions Pagination Dynamic elements

  9. The brute force approach Disadvantages : 1. Jaring user experience

    a. Loss of current scroll position b. UI flickers / Jitters 2. Recalculation of entire layout in the case tableview ** reloadData()
  10. Batch updates view.performBatchUpdates({ () -> Void in view.insertItemsAtIndexPaths([ Indexpath1,indexpath2]) view.deleteItemsAtIndexPaths([

    Indexpath1,indexpath2]) }, completion:nil) view - UITableView / UICollectionView instance
  11. D’oh!

  12. What just happened? Really complicated and highly error prone •

    Too many rules to remember ◦ Order, meaning and syncing • No Single centralized source of truth • Index Paths are fickle
  13. Back to reload data

  14. What’s new in iOS 13 ?

  15. Diffiable Data source API • Declarative approach to UI state.

    • Simple API preformBatchUpdate({}) apply() • Automatic diffing.
  16. Snapshot • Represents the truth of current UI state •

    Collection of Unique Sections and Item identifiers • No more index paths • NSDiffableDatasourceSnapShot class
  17. Data sources A class to mapping to CollectionView / TableView

    iOS: • UITableViewDiffableDataSource • UICollectionViewDiffableDataSource MacOS: • NSCollectionViewDiffableDataSource
  18. How do i do this ? Set Up 1. Section/Item

    models provide unique hashable identifiers 2. Create a Diffable Data source and map it to your Collection View / TableView Use 1. Create a snapshot 2. Populate the Snapshot with section and Item identifiers 3. Apply the snapshot.
  19. Demo

  20. Review Set Up 1. Section/Item models provide unique hashable identifiers

    2. Create a Diffable Data source and map it to your Collection View / TableView Use 1. Create a snapShot 2. Populate the Snapshot with section and Item identifiers 3. Apply the snapshot.
  21. • Must have a unique identifier • Get it from

    hashability conformance • You can provide your own custom identifiers Identifiers // Custom Identifiers struct MyModel: Hashable { let identifier = UUID() func hash(into hasher: inout Hasher) { hasher.combine(identifier) } static func == (lhs: MyModel, rhs: MyModel) -> Bool { return lhs.identifier == rhs.identifier } }
  22. NSDiffableDataSourceSnapShot • Create a new one NSDiffableDataSourceSnapshot<SectionID, ItemID>() • They

    work only with identifiers • Get the current snapshot - dataSource.snapshot()
  23. You can • You can query it • Operations like

    append, insert, delete etc • Edit it safely (its a copy) What All can you do with a snap shot ? API reference : https://developer.apple.com/documentation/uikit/nsdiffabledatasourcesnapshotreference
  24. Continue with demo

  25. Review • Get the current snapshot - dataSource.snapshot() • Perform

    operations on it ◦ snapShot.insertSections([SectionId], beforeSection: SectionID) • How to interact with indexPath api ◦ dataSource.itemIdentifier(for:indexPath)
  26. Performance • This api is FAST !!!!! • But Diffing

    is Its a linear operation O(N) • apply() from the background queue • Just make sure you are consistent
  27. Backward Compatibility ? • IOS 12 and below ? •

    Open source to the rescue ◦ DiffableDataSource [https://github.com/ra1028/DiffableDataSources] ◦ Difference kit [https://github.com/ra1028/DifferenceKit] ◦ Differ [https://github.com/tonyarnold/Differ]
  28. Conclusion • New Simple, Robust api for animations with a

    single centralized source of truth ◦ No performBatchupdates() only apply() • Works with SnapShots and Identifiers not indexpaths • Operation on Snapshot • Backward compatibility More Info: https://developer.apple.com/videos/play/wwdc2019/220/ https://jayeshkawli.ghost.io/ios-13-diffable-data-source-for-uitableview-and-uicollectionview/ https://developer.apple.com/documentation/uikit/nsdiffabledatasourcesnapshotreference
  29. Questions ?

  30. Thank you