# API Reference The `DataSourceController` provides an API to dinamically insert, update or remove individual rows and sections. Most of this API is declared by the protocols `RowManager` and `SectionManager`. In addition, there are several additional helper functions and properties implemented in the main class. ## Helper functions and properties ```swift weak var delegate: DataSourceControllerDelegate? { get set } ``` Returns or sets the `DataSourceController` delegate property, as described in the [DataSourceControllerDelegate](README.md#datasourcecontrollerdelegate) section of the README, which is notified of the changes in rows and sections of the controller. It's optional, and can be set either during or after the initialization. -------------------------------------------------- ```swift var totalRowCount: Int { get } ``` Returns the total number of rows currently present in all the `Section` instances of this `DataSourceController` instance. Note that the number of sections is usually not 0 as per implementation, since every initializer does create at least one `Section` instance and the only way to reduce this number to 0 is to manually call functions to remove them. Therefore this is the property to check for "emptyness". -------------------------------------------------- ```swift func modelObject(at indexPath: IndexPath) -> Any? ``` Returns the model object instance at the selected `indexPath`. If the `indexPath` is out of bounds on either the `section` or the `row` properties, this function returns `nil` without crashing. -------------------------------------------------- ```swift func data(for section: Int) -> SectionDataModelType? ``` Returns the `SectionDataModelType` conforming object for the selected `section` index. If no section data has been provided or `section` is out of bounds, this function returns `nil` without crashing. -------------------------------------------------- ```swift func register(dataController: CellDataController.Type, for model: Any.Type) ``` Registers the `CellDataController` conforming type to be used with the `model` specific type. A few notes on this: * The same controller can be used safely with different model objects. * Only a single controller type may be registered to a given model object type. Successive calls to this function with the same model object type will result in any previous registered controller type being overwritten. ## RowManager protocol ```swift func add(row modelObject: Any, at indexPath: IndexPath, notify: Bool) ``` Inserts a new row at the given `indexPath`. There are several different outcomes depending on the `indexPath` passed as a parameter. * If `indexPath.section` is out of bounds, a new `Section` with a single row is inserted at the end of the `Section` array. * If `indexPath.section` is within bounds, but `indexPath.row` is out of bounds, a new row is inserted at the end of the given `Section`. * If both `indexPath.section` and `indexPath.row` are within bounds, the new row is inserted at the specified position of the given `Section`, moving "down" the rows behind the newly inserted one. If `notify` is `true`, the following code is executed: ```swift delegate?.dataSourceWasMutated(self, section: indexPath.section) ``` -------------------------------------------------- ```swift func update(row modelObject: Any, at indexPath: IndexPath, notify: Bool) ``` Updates the model object at the given `indexPath`. There are several different outcomes depending on the `indexPath` passed as a parameter. * If either `indexPath.section` or `indexPath.row` are out of bounds, the function returns without performing any further action. No notification function in the delegate will be called. * If both `indexPath.section` and `indexPath.row` are within bounds, the model object at the given `indexPath` is replaced by the new instance `modelObject` passed as a parameter. If `notify` is `true`, the following code is executed: ```swift delegate?.dataSourceWasMutated(self, rows: [indexPath]) ``` -------------------------------------------------- ```swift func update(rows: [Any], atSection index: Int, notify: Bool) ``` Replaces all the model objects at the `Section` at position `index` by the `rows` passed as a parameter. * If `atSection` is out of bounds, the function returns without performing any further action. No notification function in the delegate will be called. * If `atSection` is within bounds, the value in the `rows` property of that `Section` instance is replaced by the new value `rows` passed to the function. **Note:** Only the model objects in the rows are replaced, whilst section data remains unmodified. If `notify` is `true`, the following code is executed: ```swift delegate?.dataSourceWasMutated(self, rows: (0..<rows.count).map { IndexPath(row: $0, section: index) }) ``` -------------------------------------------------- ```swift func update(rows: [IndexPath: Any], notify: Bool) ``` Replaces the model objects at the `IndexPath`'s provided by the keys of the dictionary `rows` by the new model objects provided by its values. * If the maximum `indexPath.section` index in the keys of `rows` is out of bounds, the function returns without performing any further action. No notification in the delegate will be called. * If `indexPath.row` of a given object is out of bounds in that specific `Section` rows, that model object is not updated but the implementation will continue with the remaining model objects. * If `indexPath.row` of a given object is within bounds, that model object is replaced by the new instance. If `notify` is `true`, the following code is executed: ```swift delegate?.dataSourceWasMutated(self, rows: mutatedIndexPaths) ``` where `mutatedIndexPaths` are the `indexPath`s of the rows that have been updated (that is, the one that are not skipped due to an out of bounds row index) -------------------------------------------------- ```swift func remove(rowAt indexPath: IndexPath, notify: Bool) ``` Removes the model object at the given `indexPath`. There are several different outcomes depending on the `indexPath` passed as a parameter. * If either `indexPath.section` or `indexPath.row` are out of bounds, the function returns without performing any further action. No notification function in the delegate will be called. * If both `indexPath.section` and `indexPath.row` are within bounds, the model object at the given `indexPath` is removed. If the `Section` instance containing the model object that has been removed is reduced to 0 elements, then the entire `Section` is removed. If `notify` is `true`, the following code is executed: ```swift delegate?.dataSourceWasMutated(self) ``` ## SectionManager protocol ```swift func add(section: Section, at index: Int?, notify: Bool) ``` Inserts a new `section` at the given `index`. There are several different outcomes depending on the `index` passed as a parameter. * If `index` is `nil` or out of bounds, the `section` is inserted at the end of the `Section` array. * If `index` is not nil and within bounds, the `section` is inserted at the position given by `index` Note that may be omitted when calling the function, in which case its value defaults to `nil`. If `notify` is `true`, the following code is executed: ```swift delegate?.dataSourceWasMutated(self) ``` -------------------------------------------------- ```swift func update(sectionData: SectionDataModelType, at index: Int, notify: Bool) ``` Updates the `sectionData` of the `Section` instance at the given `index`. There are several different outcomes depending on the `index` passed as a parameter. * If `index` is out of bounds, the function returns without performing any further action. No notification function in the delegate will be called. * If `index` is within bounds, the `sectionData` property of the section object at the given `index` is replaced by the new instance `sectionData` passed as a parameter. **Note:** Only the section data is updated, whilst the model objects in the rows remain unmodified. If `notify` is `true`, the following code is executed: ```swift delegate?.dataSourceWasMutated(self, section: index) ``` -------------------------------------------------- ```swift func update(section: Section, at index: Int, notify: Bool) ``` Updates the `section` at the given `index`. There are several different outcomes depending on the `index` passed as a parameter. * If `index` is out of bounds, the function returns without performing any further action. No notification function in the delegate will be called. * If `index` is within bounds, the section object at the given `index` is replaced by the new instance `section` passed as a parameter. **Note:** This function replaces both the section data and the rows, and may be considered as calling the following two functions: ```swift let dataSourceController: DataSourceController ... let newSection = createNewSection() dataSourceController.update(rows: newSection.rows, atSection: index, notify: false) dataSourceController.update(sectionData: newSection.sectionData, at: index, notify: true) ``` If `notify` is `true`, the following code is executed: ```swift delegate?.dataSourceWasMutated(self, section: index) ``` -------------------------------------------------- ```swift func update(allSections sections: [Section], notify: Bool) ``` Replaces all the section objects in the `DataSourceController` instance by the `sections` array passed as a parameter. If `notify` is `true`, the following code is executed: ```swift delegate?.dataSourceWasMutated(self) ``` -------------------------------------------------- ```swift func remove(sectionAt index: Int, notify: Bool) ``` Removes the section object at the given `index`. There are several different outcomes depending on the `index` passed as a parameter. * If `index` is out of bounds, the function returns without performing any further action. No notification function in the delegate will be called. * If `index` is within bounds, the section object at the given `index` is removed. If `notify` is `true`, the following code is executed: ```swift delegate?.dataSourceWasMutated(self) ``` -------------------------------------------------- ```swift func removeAllSections(notify: Bool) ``` Removes all the section objects in the `DataSourceController` instance. If `notify` is `true`, the following code is executed: ```swift delegate?.dataSourceWasMutated(self) ```