Skip to content

Concise, flexible, and UI independent protocol for data sources

License

Notifications You must be signed in to change notification settings

ezcater/DataSource

Repository files navigation

Deprecated

This project is considered deprecated and is no longer receiving updates. You may want to check out Apple's UICollectionViewDiffableDataSource.

DataSource

Swift 5.0

DataSource is a concise and UI independent protocol for representing data sources. It can be used out of the box, but is also extremely flexible in case any customization is required.

At it's core, DataSource is a simple protocol. It requires a ItemType, which represents the type of the contained objects.

public protocol DataSource {
    associatedtype ItemType

    var reloadBlock: ReloadBlock? { get set }
    var numberOfSections: Int { get }

    func numberOfItems(in section: Int) -> Int
    func item(at indexPath: IndexPath) -> ItemType?
    func indexPath(after indexPath: IndexPath) -> IndexPath?
}

It uses a closure, ReloadBlock, to communicate a ChangeSet in the backing data.

public typealias ReloadBlock = (ChangeSet) -> Void

A ChangeSet is a set of Changes to be performed to the corresponding UI element (UITableView or UICollectionView).

public enum ChangeSet {
    case some([Change])
    case all
}

public enum Change {
    case section(type: ChangeType)
    case object(type: ChangeType)
}

public enum ChangeType {
    case insert(IndexPath)
    case delete(IndexPath)
    case move(IndexPath, IndexPath)
    case update(IndexPath)
}

ListDataSource

ListDataSource inherits from DataSource and represents a single section backed by an array.

public protocol ListDataSource: DataSource {
    var items: [ItemType] { get }
}

It includes default implementations for:

  • var numberOfSections: Int
  • func numberOfItems(in section: Int) -> Int
  • func item(at indexPath: IndexPath) -> ItemType?
  • func indexPath(after indexPath: IndexPath) -> IndexPath?

Example

class SimpleDataSource: ListDataSource {
    typealias ItemType = String

    var items = [
        "Item 0",
        "Item 1",
        "Item 2"
    ]

    var reloadBlock: ReloadBlock?
}

SectionedDataSource

SectionedDataSource inherits from DataSource and represents multiple sections, each backed by a Section.

public protocol SectionedDataSource: DataSource {
    associatedtype SectionType: Section<ItemType>

    var sections: [SectionType] { get }

    func section(at index: Int) -> SectionType?
    func headerTitle(for section: Int) -> String?
    func footerTitle(for section: Int) -> String?
}

It includes default implementations for:

  • var numberOfSections: Int
  • func numberOfItems(in section: Int) -> Int
  • func item(at indexPath: IndexPath) -> ItemType?
  • func indexPath(after indexPath: IndexPath) -> IndexPath?
  • func section(at index: Int) -> SectionType?
  • func headerTitle(for section: Int) -> String?
  • func footerTitle(for section: Int) -> String?

Example

class SimpleDataSource: SectionedDataSource {
    typealias ItemType = String
    typealias SectionType = Section<String>

    var sections = [
        Section(items: ["Item 0.0", "Item 0.1", "Item 0.2"]),
        Section(items: ["Item 1.0", "Item 1.1"], headerTitle: "Header 1"),
        Section(items: ["Item 2.0"], headerTitle: "Header 2", footerTitle: "Footer 2")
    ]

    var reloadBlock: ReloadBlock?
}

Section

Section objects each represent a single section. It includes an array of ItemType items and optionally a header or footer title. It is subclassable if any additional functionality is needed.

open class Section<ItemType> {
    public var items: [ItemType]
    public var headerTitle: String?
    public var footerTitle: String?

    public init(items: [ItemType], headerTitle: String? = nil, footerTitle: String? = nil) {
        self.items = items
        self.headerTitle = headerTitle
        self.footerTitle = footerTitle
    }
}

FetchedDataSource

FetchedDataSource inherits from DataSource and represents a NSFetchResultsController backed list.

public protocol FetchedDataSource: DataSource {
    associatedtype ItemType: NSFetchRequestResult

    var fetchedResultsController: NSFetchedResultsController<ItemType> { get }
}

It includes default implementations for:

  • var numberOfSections: Int
  • func numberOfItems(in section: Int) -> Int
  • func item(at indexPath: IndexPath) -> ItemType?
  • func indexPath(after indexPath: IndexPath) -> IndexPath?

Requirements

DataSource requires Swift 5.0 and iOS 12.0+

Installation

DataSource is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "EZDataSource"

Author

Brad Smith

Maintainers

ezCater Mobile Team, dev-mobile-team@ezcater.com

License

DataSource is available under the MIT license. See the LICENSE file for more info.

About

Concise, flexible, and UI independent protocol for data sources

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published