Skip to content

Latest commit

 

History

History
150 lines (100 loc) · 7.99 KB

7.0 Migration Guide.md

File metadata and controls

150 lines (100 loc) · 7.99 KB

DTCollectionViewManager 7.0 Migration Guide

DTCollectionViewManager 7.0 is the latest major release of UICollectionView helper library for iOS and tvOS written in Swift. Following Semantic Versioning conventions, 7.0 introduces API-breaking changes.

This guide is provided in order to ease the transition of existing applications using 6.x versions to the latest APIs, as well as explain the design and structure of new and updated functionality.

Requirements

  • iOS 8.0 and higher / tvOS 9.0 and higher
  • Xcode 9.x and higher
  • Swift 4.2 and higher
  • DTModelStorage 8.0 and higher

Benefits of Upgrading

  • Support for Diffable DataSources in iOS / tvOS 13.
  • Unified supplementary model API
  • Support for new iOS 13 delegate API

Breaking API Changes

Supplementary providers

In previous releases various storages from DTModelStorage had several API's to work with supplementaries. This could create confusion to how those APIs should be used, as well as prevented support for diffable datasources, which delegate construction of sections to developer. So starting with DTModelStorage 8.0, header and footer API has been rewritten to be closure-based. You can read more about those changes in DTModelStorage 8.0 Migration Guide

Regarding DTCollectionViewManager part of those changes, there are several important things to remember:

  • Setting supplementary models does not trigger UICollectionView.reloadData() anymore, so it needs to be called manually if you need to update supplementary views when this method is called. If you set header/footer/supplementary providers before UICollectionView comes on screen, calling reloadData is not necessary.
  • SupplementaryAccessible protocol with corresponding extensions collectionHeaderModel and collectionFooterModel has been removed. If you need to get header/footer model from section, call storage.header/footerModel(for:) method.

DTCollectionViewManageable

DTCollectionViewManageable is a protocol, that is implemented to let DTCollectionViewManager know, how to communicate with UICollectionView. Previously, there was a second protocol - DTCollectionViewNonOptionalManageable to allow working with UICollectionView, that is declared as non-optional.

In 7.0 release DTCollectionViewNonOptionalManageable protocol has been removed and it's functionality has been merged into DTCollectionViewManageable, which now has two properties:

  • collectionView
  • optionalCollectionView

One of those properties (it does not matter which one), is required to return a non-nil UICollectionView instance for DTCollectionViewManager to work.

WARNING Because of default implementations for new property this will not show as a compile error, instead crashing in runtime. Please make sure to update all definitions of

var collectionView: UICollectionView?

to

var collectionView: UICollectionView!.

If you need optional collection view, use optionalCollectionView property instead.

Other breaking changes

Previously deprecated ViewModelMappinCustomizing protocol has been removed. Please use conditional mappings feature instead.

collectionViewUpdater is now an optional property and will contain nil, if diffable datasources are used.

New Features

Diffable datasources

Diffable datasources is a cool new feature, that is introduced in UIKit in iOS / tvOS 13. DTCollectionViewManager 7 provides a powerful integration layer with it, but in order to understand how this layer works, it's highly recommended to check out great Advances in UI Data Sources WWDC session.

If you don't use DTCollectionViewManager, you would typically create diffable datasource like so (taken from Apple's sample code on diffable datasources):

dataSource = UICollectionViewDiffableDataSource
    <Section, MountainsController.Mountain>(collectionView: mountainsCollectionView) {
        (collectionView: UICollectionView, indexPath: IndexPath,
        mountain: MountainsController.Mountain) -> UICollectionViewCell? in
    guard let mountainCell = collectionView.dequeueReusableCell(
        withReuseIdentifier: LabelCell.reuseIdentifier, for: indexPath) as? LabelCell else {
            fatalError("Cannot create new cell") }
    mountainCell.label.text = mountain.name
    return mountainCell
}

One of DTCollectionViewManagers main goals is to get rid of String identifiers, and to handle cell creation, as well as updating cell with it's model, for you. Which is why with DTCollectionViewManager 7 code, equivalent to one above, is the following:

dataSource = manager.configureDiffableDataSource { indexPath, model in
    return model
}

As before, ModelTransfer protocol is used to deliver data model to the cell:

class MountainCell: UICollectionViewCell, ModelTransfer {
    @IBOutlet weak var titleLabel: UILabel!
    
    func update(with model: Mountain) {
        titleLabel.text = model.name
    } 
}
}

You should persist strong reference to dataSource object, and use it for constructing sections and items exactly as described in Apple documentation and WWDC session.

Diffable datasources and DTCollectionViewManager 7 are tightly integrated, so all events, even datasource ones like manager.configure(_:), continue to work in the same way as they were working before.

Events integration is possible, because DTCollectionViewManager injects a special ProxyDiffableDataSourceStorage object between UICollectionViewDiffableDataSource and UICollectionView. This storage does not store data models and just queries diffable data source to receive them. It does, however, implement section supplementary model providers.

DTCollectionViewManager supports both generic UICollectionViewDiffableDataSource<SectionType,ItemType> and non-generic UICollectionViewDiffableDataSourceReference with the same method name(configureDiffableDataSource). Resulting diffable datasource type is inferred from your declaration of the datasource.

Note Due to underlying implementation details, using UICollectionViewDiffableDataSource.supplementaryViewProvider property is not supported. Please use ProxyDiffableDataSourceStorage.supplementaryModelProvider property instead:

manager.supplementaryStorage?.setSectionHeaderModels(["Foo"])

iOS 13 API

iOS 13 SDK has a few new delegate methods for UICollectionView, and they are wrapped in event closures:

  • shouldBeginMultipleSelectionInteraction
  • didBeginMultipleSelectionInteraction
  • didEndMultipleSelectionInteraction
  • contextMenuConfiguration(for:)
  • previewForHighlightingContextMenu
  • previewForDismissingContextMenu
  • willCommitMenuWithAnimator

Also, events for several methods that were deprecated in iOS 13 SDK, are now deprecated in DTCollectionViewManager:

  • shouldShowMenuForItemAt
  • canPerformAction
  • performAction

Bugfixes and improvements

There is a bunch of bugfixes and improvements in this release, including:

  • Support for custom bundles for supplementary views
  • Ability to implement supplementary views on your DTCollectionViewManageable type, bypassing storage

For more, please read a detailed changelog.