From f2efe175e580a72501cce29b5d75447d69dbb799 Mon Sep 17 00:00:00 2001 From: John Estropia Date: Sun, 21 Feb 2021 10:17:58 +0900 Subject: [PATCH] deprecate misleading API for sectionIndexTransformers --- Sources/CSSectionBy.swift | 4 +- Sources/From+Querying.swift | 315 +++++++++++++++--- ...Internals.DiffableDataSourceSnapshot.swift | 61 +++- .../Internals.DiffableDataUIDispatcher.swift | 5 + ...edDiffableDataSourceSnapshotDelegate.swift | 10 +- ...als.FetchedResultsControllerDelegate.swift | 9 +- Sources/ListMonitor.swift | 18 +- Sources/ListPublisher.swift | 18 +- Sources/ObjectMonitor.swift | 12 +- Sources/SectionBy.swift | 288 +++++++++++++--- 10 files changed, 601 insertions(+), 139 deletions(-) diff --git a/Sources/CSSectionBy.swift b/Sources/CSSectionBy.swift index 0f2751a..fe829e7 100644 --- a/Sources/CSSectionBy.swift +++ b/Sources/CSSectionBy.swift @@ -51,10 +51,10 @@ public final class CSSectionBy: NSObject { } /** - Initializes a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Initializes a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title - returns: a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections */ @objc diff --git a/Sources/From+Querying.swift b/Sources/From+Querying.swift index 9a27c0d..483b438 100644 --- a/Sources/From+Querying.swift +++ b/Sources/From+Querying.swift @@ -71,7 +71,10 @@ extension From { - parameter args: the arguments for `format` - returns: a `FetchChainBuilder` with a predicate using the specified string format and arguments */ - public func `where`(format: String, _ args: Any...) -> FetchChainBuilder { + public func `where`( + format: String, + _ args: Any... + ) -> FetchChainBuilder { return self.fetchChain(appending: Where(format, argumentArray: args)) } @@ -83,7 +86,10 @@ extension From { - parameter argumentArray: the arguments for `format` - returns: a `FetchChainBuilder` with a predicate using the specified string format and arguments */ - public func `where`(format: String, argumentArray: [Any]?) -> FetchChainBuilder { + public func `where`( + format: String, + argumentArray: [Any]? + ) -> FetchChainBuilder { return self.fetchChain(appending: Where(format, argumentArray: argumentArray)) } @@ -106,7 +112,10 @@ extension From { - parameter sortKeys: a series of other `SortKey`s - returns: a `FetchChainBuilder` with a series of `SortKey`s */ - public func orderBy(_ sortKey: OrderBy.SortKey, _ sortKeys: OrderBy.SortKey...) -> FetchChainBuilder { + public func orderBy( + _ sortKey: OrderBy.SortKey, + _ sortKeys: OrderBy.SortKey... + ) -> FetchChainBuilder { return self.fetchChain(appending: OrderBy([sortKey] + sortKeys)) } @@ -178,7 +187,11 @@ extension From { - parameter selectTerms: a series of `SelectTerm`s - returns: a `QueryChainBuilder` that starts with a `Select` clause created from the specified `SelectTerm`s */ - public func select(_ resultType: R.Type, _ selectTerm: SelectTerm, _ selectTerms: SelectTerm...) -> QueryChainBuilder { + public func select( + _ resultType: R.Type, + _ selectTerm: SelectTerm, + _ selectTerms: SelectTerm... + ) -> QueryChainBuilder { return self.select(resultType, [selectTerm] + selectTerms) } @@ -190,7 +203,10 @@ extension From { - parameter selectTerms: a series of `SelectTerm`s - returns: a `QueryChainBuilder` that starts with a `Select` clause created from the specified `SelectTerm`s */ - public func select(_ resultType: R.Type, _ selectTerms: [SelectTerm]) -> QueryChainBuilder { + public func select( + _ resultType: R.Type, + _ selectTerms: [SelectTerm] + ) -> QueryChainBuilder { return .init( from: self, @@ -224,19 +240,22 @@ extension From { @available(macOS 10.12, *) public func sectionBy(_ sectionKeyPath: KeyPathString) -> SectionMonitorChainBuilder { - return self.sectionBy(sectionKeyPath, { $0 }) + return self.sectionBy(sectionKeyPath, sectionIndexTransformer: { _ in nil }) } /** - Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title - returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path */ @available(macOS 10.12, *) - public func sectionBy(_ sectionKeyPath: KeyPathString, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> SectionMonitorChainBuilder { + public func sectionBy( + _ sectionKeyPath: KeyPathString, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { return .init( from: self, @@ -257,6 +276,22 @@ extension From { return .init(from: self, fetchClauses: Array(clauses)) } + + + // MARK: Deprecated + + @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") + @available(macOS 10.12, *) + public func sectionBy( + _ sectionKeyPath: KeyPathString, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } } @@ -284,21 +319,46 @@ extension From where O: NSManagedObject { @available(macOS 10.12, *) public func sectionBy(_ sectionKeyPath: KeyPath) -> SectionMonitorChainBuilder { - return self.sectionBy(sectionKeyPath._kvcKeyPathString!, { $0 }) + return self.sectionBy( + sectionKeyPath._kvcKeyPathString!, + sectionIndexTransformer: { _ in nil } + ) } /** - Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title - returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path */ @available(macOS 10.12, *) - public func sectionBy(_ sectionKeyPath: KeyPath, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> SectionMonitorChainBuilder { + public func sectionBy( + _ sectionKeyPath: KeyPath, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { - return self.sectionBy(sectionKeyPath._kvcKeyPathString!, sectionIndexTransformer) + return self.sectionBy( + sectionKeyPath._kvcKeyPathString!, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + + // MARK: Deprecated + + @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") + @available(macOS 10.12, *) + public func sectionBy( + _ sectionKeyPath: KeyPath, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + sectionKeyPath._kvcKeyPathString!, + sectionIndexTransformer: sectionIndexTransformer + ) } } @@ -371,7 +431,10 @@ extension From where O: CoreStoreObject { @available(macOS 10.12, *) public func sectionBy(_ sectionKeyPath: KeyPath.Stored>) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, { $0 }) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -383,7 +446,10 @@ extension From where O: CoreStoreObject { @available(macOS 10.12, *) public func sectionBy(_ sectionKeyPath: KeyPath.Virtual>) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, { $0 }) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -395,7 +461,10 @@ extension From where O: CoreStoreObject { @available(macOS 10.12, *) public func sectionBy(_ sectionKeyPath: KeyPath.Coded>) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, { $0 }) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -407,7 +476,10 @@ extension From where O: CoreStoreObject { @available(macOS 10.12, *) public func sectionBy(_ sectionKeyPath: KeyPath.Required>) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, { $0 }) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -419,7 +491,10 @@ extension From where O: CoreStoreObject { @available(macOS 10.12, *) public func sectionBy(_ sectionKeyPath: KeyPath.Optional>) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, { $0 }) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -431,7 +506,10 @@ extension From where O: CoreStoreObject { @available(macOS 10.12, *) public func sectionBy(_ sectionKeyPath: KeyPath.Required>) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, { $0 }) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -443,105 +521,244 @@ extension From where O: CoreStoreObject { @available(macOS 10.12, *) public func sectionBy(_ sectionKeyPath: KeyPath.Optional>) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, { $0 }) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: { _ in nil } + ) } /** - Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title - returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path */ @available(macOS 10.12, *) - public func sectionBy(_ sectionKeyPath: KeyPath.Stored>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> SectionMonitorChainBuilder { + public func sectionBy( + _ sectionKeyPath: KeyPath.Stored>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title - returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path */ @available(macOS 10.12, *) - public func sectionBy(_ sectionKeyPath: KeyPath.Virtual>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> SectionMonitorChainBuilder { + public func sectionBy( + _ sectionKeyPath: KeyPath.Virtual>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title - returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path */ @available(macOS 10.12, *) - public func sectionBy(_ sectionKeyPath: KeyPath.Coded>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> SectionMonitorChainBuilder { + public func sectionBy( + _ sectionKeyPath: KeyPath.Coded>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title - returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path */ @available(macOS 10.12, *) - public func sectionBy(_ sectionKeyPath: KeyPath.Required>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> SectionMonitorChainBuilder { + public func sectionBy( + _ sectionKeyPath: KeyPath.Required>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title - returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path */ @available(macOS 10.12, *) - public func sectionBy(_ sectionKeyPath: KeyPath.Optional>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> SectionMonitorChainBuilder { + public func sectionBy( + _ sectionKeyPath: KeyPath.Optional>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title - returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path */ @available(macOS 10.12, *) - public func sectionBy(_ sectionKeyPath: KeyPath.Required>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> SectionMonitorChainBuilder { + public func sectionBy( + _ sectionKeyPath: KeyPath.Required>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title - returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path */ @available(macOS 10.12, *) - public func sectionBy(_ sectionKeyPath: KeyPath.Optional>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> SectionMonitorChainBuilder { + public func sectionBy( + _ sectionKeyPath: KeyPath.Optional>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { - return self.sectionBy(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + + // MARK: Deprecated + + @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") + @available(macOS 10.12, *) + public func sectionBy( + _ sectionKeyPath: KeyPath.Stored>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") + @available(macOS 10.12, *) + public func sectionBy( + _ sectionKeyPath: KeyPath.Virtual>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") + @available(macOS 10.12, *) + public func sectionBy( + _ sectionKeyPath: KeyPath.Coded>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") + @available(macOS 10.12, *) + public func sectionBy( + _ sectionKeyPath: KeyPath.Required>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") + @available(macOS 10.12, *) + public func sectionBy( + _ sectionKeyPath: KeyPath.Optional>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") + @available(macOS 10.12, *) + public func sectionBy( + _ sectionKeyPath: KeyPath.Required>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") + @available(macOS 10.12, *) + public func sectionBy( + _ sectionKeyPath: KeyPath.Optional>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } } diff --git a/Sources/Internals.DiffableDataSourceSnapshot.swift b/Sources/Internals.DiffableDataSourceSnapshot.swift index c46bc38..80618eb 100644 --- a/Sources/Internals.DiffableDataSourceSnapshot.swift +++ b/Sources/Internals.DiffableDataSourceSnapshot.swift @@ -47,10 +47,16 @@ extension Internals { // MARK: Internal - init(sections: [NSFetchedResultsSectionInfo], fetchOffset: Int, fetchLimit: Int) { + init( + sections: [NSFetchedResultsSectionInfo], + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?, + fetchOffset: Int, + fetchLimit: Int + ) { self.structure = .init( sections: sections, + sectionIndexTransformer: sectionIndexTransformer, fetchOffset: Swift.max(0, fetchOffset), fetchLimit: (fetchLimit > 0) ? fetchLimit : nil ) @@ -264,11 +270,18 @@ extension Internals { internal struct Section: DifferentiableSection, Equatable { + let indexTitle: String? var isReloaded: Bool - init(differenceIdentifier: String, items: [Item] = [], isReloaded: Bool = false) { + init( + differenceIdentifier: String, + indexTitle: String?, + items: [Item] = [], + isReloaded: Bool = false + ) { self.differenceIdentifier = differenceIdentifier + self.indexTitle = indexTitle self.elements = items self.isReloaded = isReloaded } @@ -292,6 +305,7 @@ extension Internals { self.init( differenceIdentifier: source.differenceIdentifier, + indexTitle: source.indexTitle, items: Array(elements), isReloaded: source.isReloaded ) @@ -329,16 +343,23 @@ extension Internals { // MARK: Internal + let sectionIndexTransformer: (_ sectionName: String?) -> String? var sections: [Section] private(set) var reloadedItems: Set init() { + self.sectionIndexTransformer = { _ in nil } self.sections = [] self.reloadedItems = [] } - init(sections: [NSFetchedResultsSectionInfo], fetchOffset: Int, fetchLimit: Int?) { + init( + sections: [NSFetchedResultsSectionInfo], + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?, + fetchOffset: Int, + fetchLimit: Int? + ) { let sliceItems: (_ array: [Any], _ offset: Int) -> Array.SubSequence if let fetchLimit = fetchLimit { @@ -373,9 +394,14 @@ extension Internals { continue } newSections.append( - Section(differenceIdentifier: section.name, items: items) + Section( + differenceIdentifier: section.name, + indexTitle: section.indexTitle, + items: items + ) ) } + self.sectionIndexTransformer = sectionIndexTransformer self.sections = newSections self.reloadedItems = [] } @@ -545,7 +571,14 @@ extension Internals { mutating func append(sectionIDs: C) where C.Element == String { - let newSections = sectionIDs.lazy.map({ Section(differenceIdentifier: $0) }) + let sectionIndexTransformer = self.sectionIndexTransformer + let newSections = sectionIDs.lazy.map { + + return Section( + differenceIdentifier: $0, + indexTitle: sectionIndexTransformer($0) + ) + } self.sections.append(contentsOf: newSections) } @@ -555,7 +588,14 @@ extension Internals { Internals.abort("Section \"\(beforeSectionID)\" does not exist") } - let newSections = sectionIDs.lazy.map({ Section(differenceIdentifier: $0) }) + let sectionIndexTransformer = self.sectionIndexTransformer + let newSections = sectionIDs.lazy.map { + + return Section( + differenceIdentifier: $0, + indexTitle: sectionIndexTransformer($0) + ) + } self.sections.insert(contentsOf: newSections, at: sectionIndex) } @@ -565,8 +605,15 @@ extension Internals { Internals.abort("Section \"\(afterSectionID)\" does not exist") } + let sectionIndexTransformer = self.sectionIndexTransformer let sectionIndex = self.sections.index(after: beforeIndex) - let newSections = sectionIDs.lazy.map({ Section(differenceIdentifier: $0) }) + let newSections = sectionIDs.lazy.map { + + return Section( + differenceIdentifier: $0, + indexTitle: sectionIndexTransformer($0) + ) + } self.sections.insert(contentsOf: newSections, at: sectionIndex) } diff --git a/Sources/Internals.DiffableDataUIDispatcher.swift b/Sources/Internals.DiffableDataUIDispatcher.swift index a77d33b..15f70b9 100644 --- a/Sources/Internals.DiffableDataUIDispatcher.swift +++ b/Sources/Internals.DiffableDataUIDispatcher.swift @@ -191,6 +191,11 @@ extension Internals { } return self.sections[section].elements.count } + + func sectionIndexTitles() -> [String] { + + return self.sections.compactMap({ $0.indexTitle }) + } // MARK: Private diff --git a/Sources/Internals.FetchedDiffableDataSourceSnapshotDelegate.swift b/Sources/Internals.FetchedDiffableDataSourceSnapshotDelegate.swift index dd1196b..760be1a 100644 --- a/Sources/Internals.FetchedDiffableDataSourceSnapshotDelegate.swift +++ b/Sources/Internals.FetchedDiffableDataSourceSnapshotDelegate.swift @@ -41,9 +41,9 @@ import AppKit internal protocol FetchedDiffableDataSourceSnapshotHandler: AnyObject { - func controller(_ controller: NSFetchedResultsController, didChangeContentWith snapshot: Internals.DiffableDataSourceSnapshot) + var sectionIndexTransformer: (_ sectionName: KeyPathString?) -> String? { get } - func controller(_ controller: NSFetchedResultsController, sectionIndexTitleForSectionName sectionName: String?) -> String? + func controller(_ controller: NSFetchedResultsController, didChangeContentWith snapshot: Internals.DiffableDataSourceSnapshot) } @@ -92,6 +92,7 @@ extension Internals { var snapshot = Internals.DiffableDataSourceSnapshot( sections: controller.sections ?? [], + sectionIndexTransformer: self.handler.map({ $0.sectionIndexTransformer }) ?? { _ in nil }, fetchOffset: controller.fetchRequest.fetchOffset, fetchLimit: controller.fetchRequest.fetchLimit ) @@ -109,10 +110,7 @@ extension Internals { @objc dynamic func controller(_ controller: NSFetchedResultsController, sectionIndexTitleForSectionName sectionName: String) -> String? { - return self.handler?.controller( - controller, - sectionIndexTitleForSectionName: sectionName - ) + return self.handler?.sectionIndexTransformer(sectionName) } @objc diff --git a/Sources/Internals.FetchedResultsControllerDelegate.swift b/Sources/Internals.FetchedResultsControllerDelegate.swift index 2f88035..4cfec36 100644 --- a/Sources/Internals.FetchedResultsControllerDelegate.swift +++ b/Sources/Internals.FetchedResultsControllerDelegate.swift @@ -32,6 +32,8 @@ import CoreData @available(macOS 10.12, *) internal protocol FetchedResultsControllerHandler: AnyObject { + var sectionIndexTransformer: (_ sectionName: KeyPathString?) -> String? { get } + func controller(_ controller: NSFetchedResultsController, didChangeObject anObject: Any, atIndexPath indexPath: IndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) func controller(_ controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) @@ -39,8 +41,6 @@ internal protocol FetchedResultsControllerHandler: AnyObject { func controllerWillChangeContent(_ controller: NSFetchedResultsController) func controllerDidChangeContent(_ controller: NSFetchedResultsController) - - func controller(_ controller: NSFetchedResultsController, sectionIndexTitleForSectionName sectionName: String?) -> String? } @@ -253,10 +253,7 @@ extension Internals { @objc dynamic func controller(_ controller: NSFetchedResultsController, sectionIndexTitleForSectionName sectionName: String) -> String? { - return self.handler?.controller( - controller, - sectionIndexTitleForSectionName: sectionName - ) + return self.handler?.sectionIndexTransformer(sectionName) } diff --git a/Sources/ListMonitor.swift b/Sources/ListMonitor.swift index 847cc06..168a448 100644 --- a/Sources/ListMonitor.swift +++ b/Sources/ListMonitor.swift @@ -1008,7 +1008,7 @@ public final class ListMonitor: Hashable { fileprivate var fetchedResultsController: Internals.CoreStoreFetchedResultsController fileprivate let taskGroup = DispatchGroup() - fileprivate let sectionIndexTransformer: (_ sectionName: KeyPathString?) -> String? + internal let sectionByIndexTransformer: (_ sectionName: KeyPathString?) -> String? private let isSectioned: Bool @@ -1092,11 +1092,11 @@ public final class ListMonitor: Hashable { if let sectionIndexTransformer = sectionBy?.sectionIndexTransformer { - self.sectionIndexTransformer = sectionIndexTransformer + self.sectionByIndexTransformer = sectionIndexTransformer } else { - self.sectionIndexTransformer = { $0 } + self.sectionByIndexTransformer = { _ in nil } } self.transactionQueue = transactionQueue self.applyFetchClauses = applyFetchClauses @@ -1279,7 +1279,7 @@ extension ListMonitor where O: CoreStoreObject { } - // MARK: - Deprecated + // MARK: Deprecated @available(*, deprecated, renamed: "O") public typealias D = O @@ -1293,6 +1293,11 @@ extension ListMonitor: FetchedResultsControllerHandler { // MARK: FetchedResultsControllerHandler + internal var sectionIndexTransformer: (_ sectionName: KeyPathString?) -> String? { + + return self.sectionByIndexTransformer + } + internal func controller(_ controller: NSFetchedResultsController, didChangeObject anObject: Any, atIndexPath indexPath: IndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { switch type { @@ -1392,11 +1397,6 @@ extension ListMonitor: FetchedResultsControllerHandler { object: self ) } - - internal func controller(_ controller: NSFetchedResultsController, sectionIndexTitleForSectionName sectionName: String?) -> String? { - - return self.sectionIndexTransformer(sectionName) - } } diff --git a/Sources/ListPublisher.swift b/Sources/ListPublisher.swift index d4aea23..95446fb 100644 --- a/Sources/ListPublisher.swift +++ b/Sources/ListPublisher.swift @@ -243,6 +243,8 @@ public final class ListPublisher: Hashable { // MARK: Internal + + internal private(set) lazy var context: NSManagedObjectContext = self.fetchedResultsController.managedObjectContext internal convenience init(dataStack: DataStack, from: From, sectionBy: SectionBy?, applyFetchClauses: @escaping (_ fetchRequest: Internals.CoreStoreFetchRequest) -> Void) { @@ -299,7 +301,7 @@ public final class ListPublisher: Hashable { self.query = ( from: from, sectionBy: sectionBy, - sectionIndexTransformer: sectionBy?.sectionIndexTransformer ?? { $0 }, + sectionIndexTransformer: sectionBy?.sectionIndexTransformer ?? { _ in nil }, applyFetchClauses: applyFetchClauses ) (self.fetchedResultsController, self.fetchedResultsControllerDelegate) = (newFetchedResultsController, newFetchedResultsControllerDelegate) @@ -336,8 +338,6 @@ public final class ListPublisher: Hashable { private lazy var observers: NSMapTable, Void>> = .weakToStrongObjects() - private lazy var context: NSManagedObjectContext = self.fetchedResultsController.managedObjectContext - private static func recreateFetchedResultsController(context: NSManagedObjectContext, from: From, sectionBy: SectionBy?, applyFetchClauses: @escaping (_ fetchRequest: Internals.CoreStoreFetchRequest) -> Void) -> (controller: Internals.CoreStoreFetchedResultsController, delegate: Internals.FetchedDiffableDataSourceSnapshotDelegate) { let fetchRequest = Internals.CoreStoreFetchRequest() @@ -365,7 +365,7 @@ public final class ListPublisher: Hashable { self.query = ( from: from, sectionBy: sectionBy, - sectionIndexTransformer: sectionBy?.sectionIndexTransformer ?? { $0 }, + sectionIndexTransformer: sectionBy?.sectionIndexTransformer ?? { _ in nil }, applyFetchClauses: applyFetchClauses ) (self.fetchedResultsController, self.fetchedResultsControllerDelegate) = Self.recreateFetchedResultsController( @@ -414,6 +414,11 @@ public final class ListPublisher: Hashable { extension ListPublisher: FetchedDiffableDataSourceSnapshotHandler { // MARK: FetchedDiffableDataSourceSnapshotHandler + + internal var sectionIndexTransformer: (_ sectionName: KeyPathString?) -> String? { + + return self.query.sectionIndexTransformer + } internal func controller(_ controller: NSFetchedResultsController, didChangeContentWith snapshot: Internals.DiffableDataSourceSnapshot) { @@ -422,11 +427,6 @@ extension ListPublisher: FetchedDiffableDataSourceSnapshotHandler { context: controller.managedObjectContext ) } - - internal func controller(_ controller: NSFetchedResultsController, sectionIndexTitleForSectionName sectionName: String?) -> String? { - - return self.query.sectionIndexTransformer(sectionName) - } } diff --git a/Sources/ObjectMonitor.swift b/Sources/ObjectMonitor.swift index 938cd0d..d550b25 100644 --- a/Sources/ObjectMonitor.swift +++ b/Sources/ObjectMonitor.swift @@ -367,7 +367,7 @@ public final class ObjectMonitor: Hashable, ObjectRepresentati } - // MARK: - Deprecated + // MARK: Deprecated @available(*, deprecated, renamed: "O") public typealias D = O @@ -381,6 +381,11 @@ extension ObjectMonitor: FetchedResultsControllerHandler { // MARK: FetchedResultsControllerHandler + internal var sectionIndexTransformer: (KeyPathString?) -> String? { + + return { _ in nil } + } + internal func controllerWillChangeContent(_ controller: NSFetchedResultsController) { NotificationCenter.default.post( @@ -416,11 +421,6 @@ extension ObjectMonitor: FetchedResultsControllerHandler { } internal func controller(_ controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) { } - - internal func controller(_ controller: NSFetchedResultsController, sectionIndexTitleForSectionName sectionName: String?) -> String? { - - return sectionName - } } diff --git a/Sources/SectionBy.swift b/Sources/SectionBy.swift index 80dad6e..43e624c 100644 --- a/Sources/SectionBy.swift +++ b/Sources/SectionBy.swift @@ -30,7 +30,7 @@ import CoreData // MARK: - SectionBy /** - The `SectionBy` clause indicates the key path to use to group the `ListMonitor` objects into sections. An optional closure can also be provided to transform the value into an appropriate section name: + The `SectionBy` clause indicates the key path to use to group the `ListMonitor` objects into sections. An optional closure can also be provided to transform the value into an appropriate section index title: ``` let monitor = dataStack.monitorSectionedList( From(), @@ -49,17 +49,23 @@ public struct SectionBy { */ public init(_ sectionKeyPath: KeyPathString) { - self.init(sectionKeyPath, { $0 }) + self.init( + sectionKeyPath, + sectionIndexTransformer: { _ in nil } + ) } /** - Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title */ - public init(_ sectionKeyPath: KeyPathString, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) { + public init( + _ sectionKeyPath: KeyPathString, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { self.sectionKeyPath = sectionKeyPath self.sectionIndexTransformer = sectionIndexTransformer @@ -76,8 +82,23 @@ public struct SectionBy { @available(*, deprecated, renamed: "O") public typealias D = O + + @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") + public init( + _ sectionKeyPath: KeyPathString, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { + + self.init( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } } + +// MARK: - SectionBy where O: NSManagedObject + @available(macOS 10.12, *) extension SectionBy where O: NSManagedObject { @@ -88,22 +109,49 @@ extension SectionBy where O: NSManagedObject { */ public init(_ sectionKeyPath: KeyPath) { - self.init(sectionKeyPath, { $0 }) + self.init( + sectionKeyPath, + sectionIndexTransformer: { _ in nil } + ) } /** - Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title */ - public init(_ sectionKeyPath: KeyPath, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) { + public init( + _ sectionKeyPath: KeyPath, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { - self.init(sectionKeyPath._kvcKeyPathString!, sectionIndexTransformer) + self.init( + sectionKeyPath._kvcKeyPathString!, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + + // MARK: Deprecated + + @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") + public init( + _ sectionKeyPath: KeyPath, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { + + self.init( + sectionKeyPath._kvcKeyPathString!, + sectionIndexTransformer: sectionIndexTransformer + ) } } + +// MARK: - SectionBy where O: CoreStoreObject + @available(macOS 10.12, *) extension SectionBy where O: CoreStoreObject { @@ -114,7 +162,10 @@ extension SectionBy where O: CoreStoreObject { */ public init(_ sectionKeyPath: KeyPath.Stored>) { - self.init(sectionKeyPath, { $0 }) + self.init( + sectionKeyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -124,7 +175,10 @@ extension SectionBy where O: CoreStoreObject { */ public init(_ sectionKeyPath: KeyPath.Virtual>) { - self.init(sectionKeyPath, { $0 }) + self.init( + sectionKeyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -134,7 +188,10 @@ extension SectionBy where O: CoreStoreObject { */ public init(_ sectionKeyPath: KeyPath.Coded>) { - self.init(sectionKeyPath, { $0 }) + self.init( + sectionKeyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -144,7 +201,10 @@ extension SectionBy where O: CoreStoreObject { */ public init(_ sectionKeyPath: KeyPath.Required>) { - self.init(sectionKeyPath, { $0 }) + self.init( + sectionKeyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -154,7 +214,10 @@ extension SectionBy where O: CoreStoreObject { */ public init(_ sectionKeyPath: KeyPath.Optional>) { - self.init(sectionKeyPath, { $0 }) + self.init( + sectionKeyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -164,7 +227,10 @@ extension SectionBy where O: CoreStoreObject { */ public init(_ sectionKeyPath: KeyPath.Required>) { - self.init(sectionKeyPath, { $0 }) + self.init( + sectionKeyPath, + sectionIndexTransformer: { _ in nil } + ) } /** @@ -174,90 +240,222 @@ extension SectionBy where O: CoreStoreObject { */ public init(_ sectionKeyPath: KeyPath.Optional>) { - self.init(sectionKeyPath, { $0 }) + self.init( + sectionKeyPath, + sectionIndexTransformer: { _ in nil } + ) } /** - Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title */ - public init(_ sectionKeyPath: KeyPath.Required>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) { + public init( + _ sectionKeyPath: KeyPath.Required>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { - self.init(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + self.init( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title */ - public init(_ sectionKeyPath: KeyPath.Stored>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) { + public init( + _ sectionKeyPath: KeyPath.Stored>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { - self.init(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + self.init( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title */ - public init(_ sectionKeyPath: KeyPath.Virtual>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) { + public init( + _ sectionKeyPath: KeyPath.Virtual>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { - self.init(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + self.init( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title */ - public init(_ sectionKeyPath: KeyPath.Coded>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) { + public init( + _ sectionKeyPath: KeyPath.Coded>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { - self.init(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + self.init( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title */ - public init(_ sectionKeyPath: KeyPath.Optional>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) { + public init( + _ sectionKeyPath: KeyPath.Optional>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { - self.init(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + self.init( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title */ - public init(_ sectionKeyPath: KeyPath.Required>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) { + public init( + _ sectionKeyPath: KeyPath.Required>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { - self.init(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + self.init( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } /** - Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name + Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name + - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title */ - public init(_ sectionKeyPath: KeyPath.Optional>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) { + public init( + _ sectionKeyPath: KeyPath.Optional>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { - self.init(O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer) + self.init( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + + // MARK: Deprecated + + @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") + public init( + _ sectionKeyPath: KeyPath.Required>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { + + self.init( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") + public init( + _ sectionKeyPath: KeyPath.Stored>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { + + self.init( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") + public init( + _ sectionKeyPath: KeyPath.Virtual>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { + + self.init( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") + public init( + _ sectionKeyPath: KeyPath.Coded>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { + + self.init( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") + public init( + _ sectionKeyPath: KeyPath.Optional>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { + + self.init( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") + public init( + _ sectionKeyPath: KeyPath.Required>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { + + self.init( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") + public init( + _ sectionKeyPath: KeyPath.Optional>, + _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) { + + self.init( + sectionKeyPath, + sectionIndexTransformer: sectionIndexTransformer + ) } }