Skip to content
This repository has been archived by the owner on Jun 19, 2018. It is now read-only.

Commit

Permalink
[TAY-44]: Reworks indexing
Browse files Browse the repository at this point in the history
Still not fully there yet, expecially with regards to being clear.
  • Loading branch information
danthorpe committed Apr 10, 2016
1 parent c69e508 commit b152711
Show file tree
Hide file tree
Showing 13 changed files with 414 additions and 82 deletions.
14 changes: 14 additions & 0 deletions Sources/Conformance/Conformance.swift
Expand Up @@ -27,6 +27,20 @@ extension NSIndexPath: IndexPathIndexType {
}
}

extension NSIndexPath: ConfigurationIndexType {

public var indexInView: NSIndexPath {
return self
}
}

extension Int: ConfigurationIndexType {

public var indexInView: Int {
return self
}
}

// MARK: - UITableView

extension UITableView: ReusableCellBasedViewType {
Expand Down
26 changes: 15 additions & 11 deletions Sources/Core/ArrayDataSource.swift
Expand Up @@ -15,10 +15,12 @@ import Foundation
By definition, it only has one "section".
*/
public class ArrayDataSource<Factory, Item where Factory: FactoryType>: CellDataSourceType {

public typealias ItemIndexType = Int
public typealias ItemType = Item
public class ArrayDataSource<
Factory, Item
where
Factory: FactoryType,
Factory.CellIndex.ViewIndex == Factory.CellIndex,
Factory.SupplementaryIndex.ViewIndex == Factory.SupplementaryIndex>: CellDataSourceType {

/// - returns: the Factory
public let factory: Factory
Expand All @@ -27,14 +29,15 @@ public class ArrayDataSource<Factory, Item where Factory: FactoryType>: CellData
public let identifier: String?

/// - returns: an optional String, for the title
public var title: String?
public var title: String? = .None

/// - returns: mapper which maps the cell index to the data source index
public let transformCellIndexToItemIndex: Factory.CellIndex -> Int = { $0.indexPath.item }
/// - returns: a closure which maps the cell index to the data source index
public let transformCellIndexToItemIndex: Factory.CellIndex.ViewIndex -> Int

/// - returns: a closure which maps the data item to what the Factory requires
public let transformItemToCellItem: Item throws -> Factory.Item

private var items: [Item]
private let items: [Item]

/**
Initializes an ArrayDataSource. It requires a factory, with an
Expand All @@ -45,11 +48,12 @@ public class ArrayDataSource<Factory, Item where Factory: FactoryType>: CellData
- parameter items: an Array of Factory.ItemType
- parameter transform: a throwing block which maps from Item to Factory.ItemType
*/
public init(identifier: String? = .None, factory: Factory, items: [Item], transform: Item throws -> Factory.Item) {
public init(identifier: String? = .None, factory: Factory, items: [Item], itemTransform: Item throws -> Factory.Item, indexTransform: Factory.CellIndex.ViewIndex -> Int) {
self.identifier = identifier
self.factory = factory
self.items = items
self.transformItemToCellItem = transform
self.transformItemToCellItem = itemTransform
self.transformCellIndexToItemIndex = indexTransform
}

/**
Expand Down Expand Up @@ -109,6 +113,6 @@ public final class BasicDataSource<
- parameter items: an Array of Factory.ItemType
*/
public init(identifier: String? = .None, factory: Factory, items: [Factory.Item]) {
super.init(identifier: identifier, factory: factory, items: items, transform: { $0 })
super.init(identifier: identifier, factory: factory, items: items, itemTransform: { $0 }, indexTransform: { $0.item })
}
}
26 changes: 18 additions & 8 deletions Sources/Core/Factory.swift
Expand Up @@ -9,12 +9,12 @@
import Foundation

/// Errors used by Factory classes
public enum FactoryError<CellIndex: IndexPathIndexType, SupplementaryIndex: IndexPathIndexType>: ErrorType, Equatable {
public enum FactoryError<CellIndex: Equatable, SupplementaryIndex: Equatable>: ErrorType, Equatable {
case NoCellRegisteredAtIndex(CellIndex)
case InvalidCellRegisteredAtIndexWithIdentifier(CellIndex, String)
}

public func == <CellIndex: IndexPathIndexType, SupplementaryIndex: IndexPathIndexType>(lhs: FactoryError<CellIndex, SupplementaryIndex>, rhs: FactoryError<CellIndex, SupplementaryIndex>) -> Bool {
public func == <CellIndex: Equatable, SupplementaryIndex: Equatable>(lhs: FactoryError<CellIndex, SupplementaryIndex>, rhs: FactoryError<CellIndex, SupplementaryIndex>) -> Bool {
switch (lhs, rhs) {
case let (.NoCellRegisteredAtIndex(lhsIndex), .NoCellRegisteredAtIndex(rhsIndex)):
return lhsIndex == rhsIndex
Expand All @@ -30,7 +30,13 @@ public func == <CellIndex: IndexPathIndexType, SupplementaryIndex: IndexPathInde
- see: FactoryType
*/
public class Factory<V, C, CI, SV, SI, I, T where V: CellBasedViewType, CI: IndexPathIndexType, SI: IndexPathIndexType>: FactoryType {
public class Factory<V, C, CI, SV, SI, I, T
where
V: CellBasedViewType,
CI: ConfigurationIndexType,
SI: ConfigurationIndexType,
V.CellIndex == CI.ViewIndex,
V.SupplementaryIndex == SI.ViewIndex>: FactoryType {

public typealias View = V

Expand All @@ -47,6 +53,7 @@ public class Factory<V, C, CI, SV, SI, I, T where V: CellBasedViewType, CI: Inde
public typealias CellConfig = (cell: Cell, item: Item, index: CellIndex) -> Void
public typealias SupplementaryViewConfig = (supplementaryView: SupplementaryView, index: SupplementaryIndex) -> Void
public typealias SupplementaryTextConfig = (index: SupplementaryIndex) -> Text?

public typealias GetCellKey = (item: Item, index: CellIndex) -> String
public typealias GetSupplementaryKey = (index: SupplementaryIndex) -> String

Expand Down Expand Up @@ -94,13 +101,12 @@ extension Factory {
public func cellForItem(item: Item, inView view: View, atIndex index: CellIndex) throws -> Cell {

let key = getCellKey?(item: item, index: index) ?? defaultCellKey
let indexPath = index.indexPath

guard let (identifier, configure) = cells[key] else {
throw Error.NoCellRegisteredAtIndex(index)
}

guard let cell = view.dequeueCellWithIdentifier(identifier, atIndexPath: indexPath) as? Cell else {
guard let cell = view.dequeueCellWithIdentifier(identifier, atIndexPath: index.indexInView) as? Cell else {
throw Error.InvalidCellRegisteredAtIndexWithIdentifier(index, identifier)
}

Expand All @@ -115,11 +121,10 @@ extension Factory {
public func supplementaryViewForKind(kind: SupplementaryElementKind, inView view: View, atIndex index: SupplementaryIndex) -> SupplementaryView? {

let key = getSupplementaryKey?(index: index) ?? defaultSupplementaryKey
let indexPath = index.indexPath

guard let
(identifier, configure) = views[SupplementaryElementIndex(kind: kind, key: key)],
supplementaryView = view.dequeueSupplementaryViewWithIdentifier(identifier, kind: kind, atIndexPath: indexPath) as? SupplementaryView
supplementaryView = view.dequeueSupplementaryViewWithIdentifier(identifier, kind: kind, atIndexPath: index.indexInView) as? SupplementaryView
else { return .None }

configure(supplementaryView: supplementaryView, index: index)
Expand All @@ -145,7 +150,12 @@ extension Factory {
- see: Factory
- see: FactoryType
*/
public class BasicFactory<V, C, SV, I where V: CellBasedViewType>: Factory<V, C, NSIndexPath, SV, NSIndexPath, I, String> {
public class BasicFactory<V, C, SV, I
where
V: CellBasedViewType,
V.CellIndex == NSIndexPath,
V.SupplementaryIndex == NSIndexPath
>: Factory<V, C, NSIndexPath, SV, NSIndexPath, I, String> {

public override init(cell: GetCellKey? = .None, supplementary: GetSupplementaryKey? = .None) {
super.init(cell: cell, supplementary: supplementary)
Expand Down
71 changes: 71 additions & 0 deletions Sources/Core/FetchedResultsDataSource.swift
@@ -0,0 +1,71 @@
//
// FetchedResultsDataSource.swift
// TaylorSource
//
// Created by Daniel Thorpe on 10/04/2016.
// Copyright © 2016 Daniel Thorpe. All rights reserved.
//

import Foundation
import CoreData

public protocol FetchedResultsController {

var delegate: NSFetchedResultsControllerDelegate? { get set }

var sections: [NSFetchedResultsSectionInfo]? { get }

func objectAtIndexPath(indexPath: NSIndexPath) -> AnyObject

func itemAtIndexPath<T>(indexPath: NSIndexPath) throws -> T
}

public class FetchedResultsDataSource<
Factory, Item
where
Factory: FactoryType,
Factory.CellIndex.ViewIndex == NSIndexPath,
Factory.CellIndex == NSIndexPath,
Factory.SupplementaryIndex.ViewIndex == Int,
Factory.SupplementaryIndex == Int>: CellDataSourceType {

public typealias ItemIndex = NSIndexPath

/// - returns: the Factory
public let factory: Factory

/// - returns: an optional String, can be used for debug identification
public let identifier: String?

/// - returns: an optional String, for the title
public var title: String? = .None

/// - returns: transform which maps the item to the cell item
public var transformItemToCellItem: Item throws -> Factory.Item

private let fetchedResultsController: FetchedResultsController

public init(identifier: String? = .None, factory: Factory, fetchedResultsController: FetchedResultsController, itemTransform: Item throws -> Factory.Item) {
self.identifier = identifier
self.factory = factory
self.fetchedResultsController = fetchedResultsController
self.transformItemToCellItem = itemTransform
}
}

public extension FetchedResultsDataSource {

var numberOfSections: Int {
return fetchedResultsController.sections?.count ?? 0
}

func numberOfItemsInSection(section: Int) -> Int {
guard let section = fetchedResultsController.sections?[section] else { return 0 }
return section.numberOfObjects
}

func itemAtIndex(index: NSIndexPath) throws -> Item {
return try fetchedResultsController.itemAtIndexPath(index)
}
}

28 changes: 14 additions & 14 deletions Sources/Interface/CellDataSourceType.swift
Expand Up @@ -27,7 +27,7 @@ public protocol CellDataSourceType: DataSourceType {
var factory: Factory { get }

/// - returns: transform which maps the cell index to the data source index
var transformCellIndexToItemIndex: Factory.CellIndex -> ItemIndex { get }
var transformCellIndexToItemIndex: Factory.CellIndex.ViewIndex -> ItemIndex { get }

/// - returns: transform which maps the item to the cell item
var transformItemToCellItem: Item throws -> Factory.Item { get }
Expand All @@ -37,14 +37,14 @@ public protocol CellDataSourceType: DataSourceType {
- parameter indexPath: An index path.
- returns: An optional item at this index path
*/
func itemAtIndex(index: Factory.CellIndex) throws -> Factory.Item
func itemAtIndex(index: Factory.CellIndex.ViewIndex) throws -> Factory.Item

/**
Vends a configured cell for the item at this index.
- parameter view: the cell based view (i.e. table view, or collection view)
- parameter index: the index for the cell.
*/
func cellForItemInView(view: Factory.View, atIndex index: Factory.CellIndex) throws -> Factory.Cell
func cellForItemInView(view: Factory.View, atIndex index: Factory.CellIndex.ViewIndex) throws -> Factory.Cell

/**
Vends an optional configured supplementary view for the correct element at index.
Expand All @@ -53,7 +53,7 @@ public protocol CellDataSourceType: DataSourceType {
- parameter index: the index for the supplementary view
- returns: an optional instance of SupplementaryViewType
*/
func supplementaryViewForElementKind(kind: SupplementaryElementKind, inView view: Factory.View, atIndex index: Factory.SupplementaryIndex) -> Factory.SupplementaryView?
func supplementaryViewForElementKind(kind: SupplementaryElementKind, inView view: Factory.View, atIndex index: Factory.SupplementaryIndex.ViewIndex) -> Factory.SupplementaryView?

/**
Vends optional text for the supplementary element at index.
Expand All @@ -62,7 +62,7 @@ public protocol CellDataSourceType: DataSourceType {
- parameter index: the index for the supplementary view
- returns: an optional instance of TextType
*/
func supplementaryTextForElementKind(kind: SupplementaryElementKind, inView view: Factory.View, atIndex index: Factory.SupplementaryIndex) -> Factory.Text?
func supplementaryTextForElementKind(kind: SupplementaryElementKind, inView view: Factory.View, atIndex index: Factory.SupplementaryIndex.ViewIndex) -> Factory.Text?
}

public extension CellDataSourceType {
Expand All @@ -74,42 +74,42 @@ public extension CellDataSourceType {
- parameter index: A cell index.
- returns: an item for the cell.
*/
public func itemAtIndex(index: Factory.CellIndex) throws -> Factory.Item {
public func itemAtIndex(index: Factory.CellIndex.ViewIndex) throws -> Factory.Item {
let item = try itemAtIndex(transformCellIndexToItemIndex(index))
return try transformItemToCellItem(item)
}
}

public extension CellDataSourceType where Factory: FactoryCellVendorType {
public extension CellDataSourceType where Factory: FactoryCellVendorType, Factory.CellIndex.ViewIndex == Factory.CellIndex {

/**
Vends a configured cell for the item at this index.
- parameter view: the cell based view (i.e. table view, or collection view)
- parameter index: the index for the cell.
*/
public func cellForItemInView(view: Factory.View, atIndex index: Factory.CellIndex) throws -> Factory.Cell {
public func cellForItemInView(view: Factory.View, atIndex index: Factory.CellIndex.ViewIndex) throws -> Factory.Cell {
let item = try itemAtIndex(index)
return try factory.cellForItem(item, inView: view, atIndex: index)
}
}

public extension CellDataSourceType where Factory: FactorySupplementaryViewVendorType {
public extension CellDataSourceType where Factory: FactorySupplementaryViewVendorType, Factory.SupplementaryIndex.ViewIndex == Factory.SupplementaryIndex {

public func supplementaryViewForElementKind(kind: SupplementaryElementKind, inView view: Factory.View, atIndex index: Factory.SupplementaryIndex) -> Factory.SupplementaryView? {
public func supplementaryViewForElementKind(kind: SupplementaryElementKind, inView view: Factory.View, atIndex index: Factory.SupplementaryIndex.ViewIndex) -> Factory.SupplementaryView? {
return factory.supplementaryViewForKind(kind, inView: view, atIndex: index)
}
}

public extension CellDataSourceType where Factory: FactorySupplementaryTextVendorType {
public extension CellDataSourceType where Factory: FactorySupplementaryTextVendorType, Factory.SupplementaryIndex.ViewIndex == Factory.SupplementaryIndex {

public func supplementaryTextForElementKind(kind: SupplementaryElementKind, inView view: Factory.View, atIndex index: Factory.SupplementaryIndex) -> Factory.Text? {
public func supplementaryTextForElementKind(kind: SupplementaryElementKind, inView view: Factory.View, atIndex index: Factory.SupplementaryIndex.ViewIndex) -> Factory.Text? {
return factory.supplementaryTextForKind(kind, atIndex: index)
}
}

public extension CellDataSourceType where Factory.CellIndex == ItemIndex {
public extension CellDataSourceType where Factory.CellIndex.ViewIndex == ItemIndex {

var transformCellIndexToItemIndex: Factory.CellIndex -> ItemIndex {
var transformCellIndexToItemIndex: Factory.CellIndex.ViewIndex -> ItemIndex {
return { $0 }
}
}
Expand Down
19 changes: 15 additions & 4 deletions Sources/Interface/DataSourceEditor.swift
Expand Up @@ -58,19 +58,30 @@ public protocol DataSourceEditor {
/// - returns: an optional CanEditItemAtIndexPath block
var canEditItemAtIndexPath: CanEditItemAtIndexPath? { get }

/// returns: an optional CommitEditActionForItemAtIndexPath block
/// - returns: an optional CommitEditActionForItemAtIndexPath block
var commitEditActionForItemAtIndexPath: CommitEditActionForItemAtIndexPath? { get }

/// returns: an optional EditActionForItemAtIndexPath block
/// - returns: an optional EditActionForItemAtIndexPath block
var editActionForItemAtIndexPath: EditActionForItemAtIndexPath? { get }

/// returns: an optional CanMoveItemAtIndexPath block
/// - returns: an optional CanMoveItemAtIndexPath block
var canMoveItemAtIndexPath: CanMoveItemAtIndexPath? { get }

/// returns: an optional CommitMoveItemAtIndexPathToIndexPath block
/// - returns: an optional CommitMoveItemAtIndexPathToIndexPath block
var commitMoveItemAtIndexPathToIndexPath: CommitMoveItemAtIndexPathToIndexPath? { get }
}

public extension DataSourceEditor {

/// - returns: a Bool to indicate whether editing is fully supported
var supportsEditing: Bool {
return canEditItemAtIndexPath != nil &&
commitEditActionForItemAtIndexPath != nil &&
canMoveItemAtIndexPath != nil &&
commitMoveItemAtIndexPathToIndexPath != nil
}
}

/**
Creates a NoEditor which can be used to make types conform to DataSourceProvider
when the underlying data source does not support editing.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Interface/DataSourceProvider.swift
Expand Up @@ -17,7 +17,7 @@ import Foundation
UITableViewDataSource, yet maintain full type fidelity of the
underlying datasource.
*/
public protocol DataSourceProvider {
public protocol DataSourceProviderType {

/// The associated datasource type
associatedtype DataSource: DataSourceType
Expand Down
2 changes: 1 addition & 1 deletion Sources/Interface/DataSourceType.swift
Expand Up @@ -17,7 +17,7 @@ import Foundation
other items for things like `UIPageViewController` or similar where the
`ItemType` may even be other data sources.
*/
public protocol DataSourceType {
public protocol DataSourceType: class {

/// The associated index type
associatedtype ItemIndex
Expand Down

0 comments on commit b152711

Please sign in to comment.