mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-17 23:13:52 +01:00
Merge branch 'develop' into prototype/containers
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "CoreStore"
|
||||
s.version = "8.0.0"
|
||||
s.version = "8.0.1"
|
||||
s.swift_version = "5.4"
|
||||
s.license = "MIT"
|
||||
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
||||
|
||||
@@ -3505,7 +3505,7 @@
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 8.0.0;
|
||||
MARKETING_VERSION = 8.0.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3528,7 +3528,7 @@
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 8.0.0;
|
||||
MARKETING_VERSION = 8.0.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3588,7 +3588,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 8.0.0;
|
||||
MARKETING_VERSION = 8.0.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3615,7 +3615,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 8.0.0;
|
||||
MARKETING_VERSION = 8.0.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3681,7 +3681,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 8.0.0;
|
||||
MARKETING_VERSION = 8.0.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3710,7 +3710,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 8.0.0;
|
||||
MARKETING_VERSION = 8.0.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3776,7 +3776,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 8.0.0;
|
||||
MARKETING_VERSION = 8.0.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3805,7 +3805,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 8.0.0;
|
||||
MARKETING_VERSION = 8.0.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
import CoreStore
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
modelVersion: "V1",
|
||||
entities: [
|
||||
Entity<Animal>("Animal"),
|
||||
Entity<Dog>("Dog"),
|
||||
Entity<Dog>("Dog", indexes: [[\Dog.$nickname, \Dog.$age]]),
|
||||
Entity<Person>("Person")
|
||||
],
|
||||
versionLock: [
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
import CoreStore
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
|
||||
@@ -32,7 +32,7 @@ let package = Package(
|
||||
.macOS(.v10_13), .iOS(.v11), .tvOS(.v11), .watchOS(.v4)
|
||||
],
|
||||
products: [
|
||||
.library(name: "CoreStore", type: .static, targets: ["CoreStore"])
|
||||
.library(name: "CoreStore", targets: ["CoreStore"])
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
|
||||
@@ -2577,7 +2577,7 @@ This installs CoreStore as a framework. Declare `import CoreStore` in your swift
|
||||
#### Install with Swift Package Manager:
|
||||
```swift
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/JohnEstropia/CoreStore.git", from: "8.0.0"))
|
||||
.package(url: "https://github.com/JohnEstropia/CoreStore.git", from: "8.0.1"))
|
||||
]
|
||||
```
|
||||
Declare `import CoreStore` in your swift file to use the library.
|
||||
|
||||
@@ -588,7 +588,7 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
entityDescription.indexes = entity.indexes.map { (compoundIndexes) in
|
||||
|
||||
return NSFetchIndexDescription.init(
|
||||
name: "_CoreStoreSchema_indexes_\(entityDescription.name!)_\(compoundIndexes.joined(separator: "-"))",
|
||||
name: "_CoreStoreSchema_indexes_\(entityDescription.name!)_\(compoundIndexes.joined(separator: "_"))",
|
||||
elements: compoundIndexes.map { (keyPath) in
|
||||
|
||||
return NSFetchIndexElementDescription(
|
||||
|
||||
@@ -154,6 +154,17 @@ extension DiffableDataSource {
|
||||
completion: completion
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a new empty `ListSnapshot` suitable for building custom lists inside subclass implementations of `apply(_:animatingDifferences:completion:)`.
|
||||
*/
|
||||
public func makeEmptySnapshot() -> ListSnapshot<O> {
|
||||
|
||||
return .init(
|
||||
diffableSnapshot: .init(),
|
||||
context: self.dataStack.unsafeContext()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the number of sections
|
||||
|
||||
@@ -44,19 +44,30 @@ internal protocol DiffableDataSourceSnapshotProtocol {
|
||||
func indexOfItem(_ identifier: NSManagedObjectID) -> Int?
|
||||
func indexOfSection(_ identifier: String) -> Int?
|
||||
|
||||
mutating func appendItems(_ identifiers: [NSManagedObjectID], toSection sectionIdentifier: String?)
|
||||
mutating func insertItems(_ identifiers: [NSManagedObjectID], beforeItem beforeIdentifier: NSManagedObjectID)
|
||||
mutating func insertItems(_ identifiers: [NSManagedObjectID], afterItem afterIdentifier: NSManagedObjectID)
|
||||
mutating func deleteItems(_ identifiers: [NSManagedObjectID])
|
||||
mutating func appendItems<C: Collection>(_ identifiers: C, toSection sectionIdentifier: String?) where C.Element == NSManagedObjectID
|
||||
mutating func insertItems<C: Collection>(_ identifiers: C, beforeItem beforeIdentifier: NSManagedObjectID) where C.Element == NSManagedObjectID
|
||||
mutating func insertItems<C: Collection>(_ identifiers: C, afterItem afterIdentifier: NSManagedObjectID) where C.Element == NSManagedObjectID
|
||||
mutating func deleteItems<C: Collection>(_ identifiers: C) where C.Element == NSManagedObjectID
|
||||
mutating func deleteAllItems()
|
||||
mutating func moveItem(_ identifier: NSManagedObjectID, beforeItem toIdentifier: NSManagedObjectID)
|
||||
mutating func moveItem(_ identifier: NSManagedObjectID, afterItem toIdentifier: NSManagedObjectID)
|
||||
mutating func reloadItems(_ identifiers: [NSManagedObjectID])
|
||||
mutating func appendSections(_ identifiers: [String])
|
||||
mutating func insertSections(_ identifiers: [String], beforeSection toIdentifier: String)
|
||||
mutating func insertSections(_ identifiers: [String], afterSection toIdentifier: String)
|
||||
mutating func deleteSections(_ identifiers: [String])
|
||||
mutating func reloadItems<C: Collection>(_ identifiers: C) where C.Element == NSManagedObjectID
|
||||
mutating func appendSections<C: Collection>(_ identifiers: C) where C.Element == String
|
||||
mutating func insertSections<C: Collection>(_ identifiers: C, beforeSection toIdentifier: String) where C.Element == String
|
||||
mutating func insertSections<C: Collection>(_ identifiers: C, afterSection toIdentifier: String) where C.Element == String
|
||||
mutating func deleteSections<C: Collection>(_ identifiers: C) where C.Element == String
|
||||
mutating func moveSection(_ identifier: String, beforeSection toIdentifier: String)
|
||||
mutating func moveSection(_ identifier: String, afterSection toIdentifier: String)
|
||||
mutating func reloadSections(_ identifiers: [String])
|
||||
mutating func reloadSections<C: Collection>(_ identifiers: C) where C.Element == String
|
||||
|
||||
mutating func unsafeAppendItems<C: Collection>(_ identifiers: C, toSectionAt sectionIndex: Int) where C.Element == NSManagedObjectID
|
||||
mutating func unsafeInsertItems<C: Collection>(_ identifiers: C, at indexPath: IndexPath) where C.Element == NSManagedObjectID
|
||||
mutating func unsafeDeleteItems<C: Collection>(at indexPaths: C) where C.Element == IndexPath
|
||||
mutating func unsafeMoveItem(at indexPath: IndexPath, to newIndexPath: IndexPath)
|
||||
mutating func unsafeReloadItems<C: Collection>(at indexPaths: C) where C.Element == IndexPath
|
||||
mutating func unsafeInsertSections<C: Collection>(_ identifiers: C, at sectionIndex: Int) where C.Element == String
|
||||
mutating func unsafeDeleteSections<C: Collection>(at sectionIndices: C) where C.Element == Int
|
||||
mutating func unsafeMoveSection(at sectionIndex: Int, to newSectionIndex: Int)
|
||||
mutating func unsafeReloadSections<C: Collection>(at sectionIndices: C) where C.Element == Int
|
||||
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ extension Internals {
|
||||
self.structure.insert(itemIDs: identifiers, after: afterIdentifier)
|
||||
}
|
||||
|
||||
mutating func deleteItems<S: Sequence>(_ identifiers: S) where S.Element == NSManagedObjectID {
|
||||
mutating func deleteItems<C: Collection>(_ identifiers: C) where C.Element == NSManagedObjectID {
|
||||
|
||||
self.structure.remove(itemIDs: identifiers)
|
||||
}
|
||||
@@ -220,7 +220,7 @@ extension Internals {
|
||||
self.structure.move(itemID: identifier, after: toIdentifier)
|
||||
}
|
||||
|
||||
mutating func reloadItems<S: Sequence>(_ identifiers: S) where S.Element == NSManagedObjectID {
|
||||
mutating func reloadItems<C: Collection>(_ identifiers: C) where C.Element == NSManagedObjectID {
|
||||
|
||||
self.structure.update(itemIDs: identifiers)
|
||||
}
|
||||
@@ -240,7 +240,7 @@ extension Internals {
|
||||
self.structure.insert(sectionIDs: identifiers, after: toIdentifier)
|
||||
}
|
||||
|
||||
mutating func deleteSections<S: Sequence>(_ identifiers: S) where S.Element == String {
|
||||
mutating func deleteSections<C: Collection>(_ identifiers: C) where C.Element == String {
|
||||
|
||||
self.structure.remove(sectionIDs: identifiers)
|
||||
}
|
||||
@@ -255,10 +255,55 @@ extension Internals {
|
||||
self.structure.move(sectionID: identifier, after: toIdentifier)
|
||||
}
|
||||
|
||||
mutating func reloadSections<S: Sequence>(_ identifiers: S) where S.Element == String {
|
||||
mutating func reloadSections<C: Collection>(_ identifiers: C) where C.Element == String {
|
||||
|
||||
self.structure.update(sectionIDs: identifiers)
|
||||
}
|
||||
|
||||
mutating func unsafeAppendItems<C: Collection>(_ identifiers: C, toSectionAt sectionIndex: Int) where C.Element == NSManagedObjectID {
|
||||
|
||||
self.structure.unsafeAppend(identifiers, toSectionAt: sectionIndex)
|
||||
}
|
||||
|
||||
mutating func unsafeInsertItems<C: Collection>(_ identifiers: C, at indexPath: IndexPath) where C.Element == NSManagedObjectID {
|
||||
|
||||
self.structure.unsafeInsert(itemIDs: identifiers, at: indexPath)
|
||||
}
|
||||
|
||||
mutating func unsafeDeleteItems<C: Collection>(at indexPaths: C) where C.Element == IndexPath {
|
||||
|
||||
self.structure.unsafeRemove(itemsAt: indexPaths)
|
||||
}
|
||||
|
||||
mutating func unsafeMoveItem(at indexPath: IndexPath, to newIndexPath: IndexPath) {
|
||||
|
||||
self.structure.unsafeMove(itemAt: indexPath, to: newIndexPath)
|
||||
}
|
||||
|
||||
mutating func unsafeReloadItems<C: Collection>(at indexPaths: C) where C.Element == IndexPath {
|
||||
|
||||
self.structure.unsafeUpdate(itemsAt: indexPaths)
|
||||
}
|
||||
|
||||
mutating func unsafeInsertSections<C: Collection>(_ identifiers: C, at sectionIndex: Int) where C.Element == String {
|
||||
|
||||
self.structure.unsafeInsert(identifiers, at: sectionIndex)
|
||||
}
|
||||
|
||||
mutating func unsafeDeleteSections<C: Collection>(at sectionIndices: C) where C.Element == Int {
|
||||
|
||||
self.structure.unsafeRemove(sectionsAt: sectionIndices)
|
||||
}
|
||||
|
||||
mutating func unsafeMoveSection(at sectionIndex: Int, to newSectionIndex: Int) {
|
||||
|
||||
self.structure.unsafeMove(sectionAt: sectionIndex, to: newSectionIndex)
|
||||
}
|
||||
|
||||
mutating func unsafeReloadSections<C: Collection>(at sectionIndices: C) where C.Element == Int {
|
||||
|
||||
self.structure.unsafeUpdate(sectionsAt: sectionIndices)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
@@ -432,13 +477,23 @@ extension Internals {
|
||||
}
|
||||
return self.sections[sectionIndex].elements.map({ $0.differenceIdentifier })
|
||||
}
|
||||
|
||||
func unsafeItem(at indexPath: IndexPath) -> NSManagedObjectID {
|
||||
|
||||
return self.sections[indexPath.section]
|
||||
.elements[indexPath.item]
|
||||
.differenceIdentifier
|
||||
}
|
||||
|
||||
func section(containing itemID: NSManagedObjectID) -> String? {
|
||||
|
||||
return self.itemPositionMap(itemID)?.section.differenceIdentifier
|
||||
}
|
||||
|
||||
mutating func append<C: Collection>(itemIDs: C, to sectionID: String?) where C.Element == NSManagedObjectID {
|
||||
mutating func append<C: Collection>(
|
||||
itemIDs: C,
|
||||
to sectionID: String?
|
||||
) where C.Element == NSManagedObjectID {
|
||||
|
||||
let index: Array<Section>.Index
|
||||
if let sectionID = sectionID {
|
||||
@@ -461,8 +516,30 @@ extension Internals {
|
||||
let items = itemIDs.lazy.map({ Item(differenceIdentifier: $0) })
|
||||
self.sections[index].elements.append(contentsOf: items)
|
||||
}
|
||||
|
||||
mutating func unsafeAppend<C: Collection>(
|
||||
_ itemIDs: C,
|
||||
toSectionAt sectionIndex: Int?
|
||||
) where C.Element == NSManagedObjectID {
|
||||
|
||||
let index: Array<Section>.Index
|
||||
if let sectionIndex = sectionIndex {
|
||||
|
||||
mutating func insert<C: Collection>(itemIDs: C, before beforeItemID: NSManagedObjectID) where C.Element == NSManagedObjectID {
|
||||
index = sectionIndex
|
||||
}
|
||||
else {
|
||||
|
||||
let section = self.sections
|
||||
index = section.index(before: section.endIndex)
|
||||
}
|
||||
let items = itemIDs.lazy.map({ Item(differenceIdentifier: $0) })
|
||||
self.sections[index].elements.append(contentsOf: items)
|
||||
}
|
||||
|
||||
mutating func insert<C: Collection>(
|
||||
itemIDs: C,
|
||||
before beforeItemID: NSManagedObjectID
|
||||
) where C.Element == NSManagedObjectID {
|
||||
|
||||
guard let itemPosition = self.itemPositionMap(beforeItemID) else {
|
||||
|
||||
@@ -473,7 +550,10 @@ extension Internals {
|
||||
.insert(contentsOf: items, at: itemPosition.itemRelativeIndex)
|
||||
}
|
||||
|
||||
mutating func insert<C: Collection>(itemIDs: C, after afterItemID: NSManagedObjectID) where C.Element == NSManagedObjectID {
|
||||
mutating func insert<C: Collection>(
|
||||
itemIDs: C,
|
||||
after afterItemID: NSManagedObjectID
|
||||
) where C.Element == NSManagedObjectID {
|
||||
|
||||
guard let itemPosition = self.itemPositionMap(afterItemID) else {
|
||||
|
||||
@@ -485,6 +565,16 @@ extension Internals {
|
||||
self.sections[itemPosition.sectionIndex].elements
|
||||
.insert(contentsOf: items, at: itemIndex)
|
||||
}
|
||||
|
||||
mutating func unsafeInsert<C: Collection>(
|
||||
itemIDs: C,
|
||||
at indexPath: IndexPath
|
||||
) where C.Element == NSManagedObjectID {
|
||||
|
||||
let items = itemIDs.lazy.map({ Item(differenceIdentifier: $0) })
|
||||
self.sections[indexPath.section].elements
|
||||
.insert(contentsOf: items, at: indexPath.item)
|
||||
}
|
||||
|
||||
mutating func remove<S: Sequence>(itemIDs: S) where S.Element == NSManagedObjectID {
|
||||
|
||||
@@ -508,6 +598,23 @@ extension Internals {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutating func unsafeRemove<S: Sequence>(itemsAt indexPaths: S) where S.Element == IndexPath {
|
||||
|
||||
var removeIndexSetMap: [Int: IndexSet] = [:]
|
||||
for indexPath in indexPaths {
|
||||
|
||||
removeIndexSetMap[indexPath.section, default: []]
|
||||
.insert(indexPath.item)
|
||||
}
|
||||
for (sectionIndex, removeIndexSet) in removeIndexSetMap {
|
||||
|
||||
for range in removeIndexSet.rangeView.reversed() {
|
||||
|
||||
self.sections[sectionIndex].elements.removeSubrange(range)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutating func removeAllItems() {
|
||||
|
||||
@@ -522,7 +629,10 @@ extension Internals {
|
||||
self.sections.removeAll(where: { $0.elements.isEmpty })
|
||||
}
|
||||
|
||||
mutating func move(itemID: NSManagedObjectID, before beforeItemID: NSManagedObjectID) {
|
||||
mutating func move(
|
||||
itemID: NSManagedObjectID,
|
||||
before beforeItemID: NSManagedObjectID
|
||||
) {
|
||||
|
||||
guard let removed = self.remove(itemID: itemID) else {
|
||||
|
||||
@@ -536,7 +646,10 @@ extension Internals {
|
||||
.insert(removed, at: itemPosition.itemRelativeIndex)
|
||||
}
|
||||
|
||||
mutating func move(itemID: NSManagedObjectID, after afterItemID: NSManagedObjectID) {
|
||||
mutating func move(
|
||||
itemID: NSManagedObjectID,
|
||||
after afterItemID: NSManagedObjectID
|
||||
) {
|
||||
|
||||
guard let removed = self.remove(itemID: itemID) else {
|
||||
|
||||
@@ -551,6 +664,17 @@ extension Internals {
|
||||
self.sections[itemPosition.sectionIndex].elements
|
||||
.insert(removed, at: itemIndex)
|
||||
}
|
||||
|
||||
mutating func unsafeMove(
|
||||
itemAt indexPath: IndexPath,
|
||||
to newIndexPath: IndexPath
|
||||
) {
|
||||
|
||||
let itemID = self.sections[indexPath.section].elements
|
||||
.remove(at: indexPath.item)
|
||||
self.sections[newIndexPath.section].elements
|
||||
.insert(itemID, at: newIndexPath.item)
|
||||
}
|
||||
|
||||
mutating func update<S: Sequence>(itemIDs: S) where S.Element == NSManagedObjectID {
|
||||
|
||||
@@ -568,6 +692,18 @@ extension Internals {
|
||||
}
|
||||
self.reloadedItems.formUnion(newItemIDs)
|
||||
}
|
||||
|
||||
mutating func unsafeUpdate<S: Sequence>(itemsAt indexPaths: S) where S.Element == IndexPath {
|
||||
|
||||
var newItemIDs: Set<NSManagedObjectID> = []
|
||||
for indexPath in indexPaths {
|
||||
|
||||
self.sections[indexPath.section]
|
||||
.elements[indexPath.item].isReloaded = true
|
||||
newItemIDs.insert(self.unsafeItem(at: indexPath))
|
||||
}
|
||||
self.reloadedItems.formUnion(newItemIDs)
|
||||
}
|
||||
|
||||
mutating func append<C: Collection>(sectionIDs: C) where C.Element == String {
|
||||
|
||||
@@ -582,7 +718,10 @@ extension Internals {
|
||||
self.sections.append(contentsOf: newSections)
|
||||
}
|
||||
|
||||
mutating func insert<C: Collection>(sectionIDs: C, before beforeSectionID: String) where C.Element == String {
|
||||
mutating func insert<C: Collection>(
|
||||
sectionIDs: C,
|
||||
before beforeSectionID: String
|
||||
) where C.Element == String {
|
||||
|
||||
guard let sectionIndex = self.sectionIndex(of: beforeSectionID) else {
|
||||
|
||||
@@ -599,7 +738,10 @@ extension Internals {
|
||||
self.sections.insert(contentsOf: newSections, at: sectionIndex)
|
||||
}
|
||||
|
||||
mutating func insert<C: Collection>(sectionIDs: C, after afterSectionID: String) where C.Element == String {
|
||||
mutating func insert<C: Collection>(
|
||||
sectionIDs: C,
|
||||
after afterSectionID: String
|
||||
) where C.Element == String {
|
||||
|
||||
guard let beforeIndex = self.sectionIndex(of: afterSectionID) else {
|
||||
|
||||
@@ -616,6 +758,22 @@ extension Internals {
|
||||
}
|
||||
self.sections.insert(contentsOf: newSections, at: sectionIndex)
|
||||
}
|
||||
|
||||
mutating func unsafeInsert<C: Collection>(
|
||||
_ sectionIDs: C,
|
||||
at sectionIndex: Int
|
||||
) where C.Element == String {
|
||||
|
||||
let sectionIndexTransformer = self.sectionIndexTransformer
|
||||
let newSections = sectionIDs.lazy.map {
|
||||
|
||||
return Section(
|
||||
differenceIdentifier: $0,
|
||||
indexTitle: sectionIndexTransformer($0)
|
||||
)
|
||||
}
|
||||
self.sections.insert(contentsOf: newSections, at: sectionIndex)
|
||||
}
|
||||
|
||||
mutating func remove<S: Sequence>(sectionIDs: S) where S.Element == String {
|
||||
|
||||
@@ -624,6 +782,16 @@ extension Internals {
|
||||
self.remove(sectionID: sectionID)
|
||||
}
|
||||
}
|
||||
|
||||
mutating func unsafeRemove<S: Sequence>(
|
||||
sectionsAt sectionIndices: S
|
||||
) where S.Element == Int {
|
||||
|
||||
for sectionIndex in sectionIndices.sorted(by: >) {
|
||||
|
||||
self.sections.remove(at: sectionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
mutating func move(sectionID: String, before beforeSectionID: String) {
|
||||
|
||||
@@ -651,8 +819,21 @@ extension Internals {
|
||||
let sectionIndex = self.sections.index(after: beforeIndex)
|
||||
self.sections.insert(removed, at: sectionIndex)
|
||||
}
|
||||
|
||||
mutating func unsafeMove(
|
||||
sectionAt sectionIndex: Int,
|
||||
to newSectionIndex: Int
|
||||
) {
|
||||
|
||||
self.sections.move(
|
||||
fromOffsets: .init(integer: sectionIndex),
|
||||
toOffset: newSectionIndex
|
||||
)
|
||||
}
|
||||
|
||||
mutating func update<S: Sequence>(sectionIDs: S) where S.Element == String {
|
||||
mutating func update<S: Sequence>(
|
||||
sectionIDs: S
|
||||
) where S.Element == String {
|
||||
|
||||
for sectionID in sectionIDs {
|
||||
|
||||
@@ -663,6 +844,16 @@ extension Internals {
|
||||
self.sections[sectionIndex].isReloaded = true
|
||||
}
|
||||
}
|
||||
|
||||
mutating func unsafeUpdate<S: Sequence>(
|
||||
sectionsAt sectionIndices: S
|
||||
) where S.Element == Int {
|
||||
|
||||
for sectionIndex in sectionIndices {
|
||||
|
||||
self.sections[sectionIndex].isReloaded = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
@@ -135,8 +135,19 @@ extension ListPublisher {
|
||||
|
||||
func cancel() {
|
||||
|
||||
self.publisher.removeObserver(self)
|
||||
self.subscriber = nil
|
||||
|
||||
if Thread.isMainThread {
|
||||
|
||||
self.publisher.removeObserver(self)
|
||||
}
|
||||
else {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
self.publisher.removeObserver(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -471,6 +471,17 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
|
||||
self.diffableSnapshot.appendItems(itemIDs, toSection: sectionID)
|
||||
}
|
||||
|
||||
/**
|
||||
Appends extra items to the specified section index
|
||||
|
||||
- parameter itemIDs: the object identifiers for the objects to append
|
||||
- parameter sectionIndex: the section index to append the items to. Specifying an invalid value will raise an exception.
|
||||
*/
|
||||
public mutating func appendItems<C: Collection>(with itemIDs: C, toSectionAt sectionIndex: Int) where C.Element == ItemID {
|
||||
|
||||
self.diffableSnapshot.unsafeAppendItems(itemIDs, toSectionAt: sectionIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
Inserts extra items before a specified item
|
||||
|
||||
@@ -493,16 +504,37 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
|
||||
self.diffableSnapshot.insertItems(itemIDs, afterItem: afterItemID)
|
||||
}
|
||||
|
||||
/**
|
||||
Inserts extra items at a specified index path
|
||||
|
||||
- parameter itemIDs: the object identifiers for the objects to insert
|
||||
- parameter indexPath: an indexPath to insert the items into. Specifying an invalid value will raise an exception.
|
||||
*/
|
||||
public mutating func insertItems<C: Collection>(withIDs itemIDs: C, at indexPath: IndexPath) where C.Element == ItemID {
|
||||
|
||||
self.diffableSnapshot.unsafeInsertItems(itemIDs, at: indexPath)
|
||||
}
|
||||
|
||||
/**
|
||||
Deletes the specified items
|
||||
|
||||
- parameter itemIDs: the object identifiers for the objects to delete
|
||||
*/
|
||||
public mutating func deleteItems<S: Sequence>(withIDs itemIDs: S) where S.Element == ItemID {
|
||||
public mutating func deleteItems<C: Collection>(withIDs itemIDs: C) where C.Element == ItemID {
|
||||
|
||||
self.diffableSnapshot.deleteItems(itemIDs)
|
||||
}
|
||||
|
||||
/**
|
||||
Deletes the items at the specified index paths
|
||||
|
||||
- parameter itemIndexPaths: the index paths for the objects to delete. Specifying an invalid value will raise an exception.
|
||||
*/
|
||||
public mutating func deleteItems<C: Collection>(at itemIndexPaths: C) where C.Element == IndexPath {
|
||||
|
||||
self.diffableSnapshot.unsafeDeleteItems(at: itemIndexPaths)
|
||||
}
|
||||
|
||||
/**
|
||||
Deletes all items
|
||||
*/
|
||||
@@ -533,16 +565,37 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
|
||||
self.diffableSnapshot.moveItem(itemID, afterItem: afterItemID)
|
||||
}
|
||||
|
||||
/**
|
||||
Moves an item at an index path to a new index path
|
||||
|
||||
- parameter itemIndexPath: an index path in the list to move. Specifying an invalid value will raise an exception.
|
||||
- parameter newIndexPath: the new index path to move the item into. Specifying an invalid value will raise an exception.
|
||||
*/
|
||||
public mutating func moveItem(at itemIndexPath: IndexPath, to newIndexPath: IndexPath) {
|
||||
|
||||
self.diffableSnapshot.unsafeMoveItem(at: itemIndexPath, to: newIndexPath)
|
||||
}
|
||||
|
||||
/**
|
||||
Marks the specified items as reloaded
|
||||
|
||||
- parameter itemIDs: the object identifiers to reload
|
||||
*/
|
||||
public mutating func reloadItems<S: Sequence>(withIDs itemIDs: S) where S.Element == ItemID {
|
||||
public mutating func reloadItems<C: Collection>(withIDs itemIDs: C) where C.Element == ItemID {
|
||||
|
||||
self.diffableSnapshot.reloadItems(itemIDs)
|
||||
}
|
||||
|
||||
/**
|
||||
Marks the specified index paths as reloaded
|
||||
|
||||
- parameter itemIndexPaths: the index paths to reload. Specifying an invalid value will raise an exception.
|
||||
*/
|
||||
public mutating func reloadItems<C: Collection>(at itemIndexPaths: C) where C.Element == IndexPath {
|
||||
|
||||
self.diffableSnapshot.unsafeReloadItems(at: itemIndexPaths)
|
||||
}
|
||||
|
||||
/**
|
||||
Appends new section identifiers to the end of the list
|
||||
|
||||
@@ -575,16 +628,37 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
|
||||
self.diffableSnapshot.insertSections(sectionIDs, afterSection: afterSectionID)
|
||||
}
|
||||
|
||||
/**
|
||||
Inserts new sections into an existing section index
|
||||
|
||||
- parameter sectionIDs: the section identifiers for the sections to insert
|
||||
- parameter sectionIndex: an existing section index to insert items into. Specifying an invalid value will raise an exception.
|
||||
*/
|
||||
public mutating func insertSections<C: Collection>(_ sectionIDs: C, at sectionIndex: Int) where C.Element == String {
|
||||
|
||||
self.diffableSnapshot.unsafeInsertSections(sectionIDs, at: sectionIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
Deletes the specified sections
|
||||
|
||||
- parameter sectionIDs: the section identifiers for the sections to delete
|
||||
*/
|
||||
public mutating func deleteSections<S: Sequence>(withIDs sectionIDs: S) where S.Element == SectionID {
|
||||
public mutating func deleteSections<C: Collection>(withIDs sectionIDs: C) where C.Element == SectionID {
|
||||
|
||||
self.diffableSnapshot.deleteSections(sectionIDs)
|
||||
}
|
||||
|
||||
/**
|
||||
Deletes the specified section indices
|
||||
|
||||
- parameter sectionIndices: the section indices to delete. Specifying an invalid value will raise an exception.
|
||||
*/
|
||||
public mutating func deleteSections<C: Collection>(at sectionIndices: C) where C.Element == Int {
|
||||
|
||||
self.diffableSnapshot.unsafeDeleteSections(at: sectionIndices)
|
||||
}
|
||||
|
||||
/**
|
||||
Moves a section before another specified section
|
||||
|
||||
@@ -607,15 +681,36 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
|
||||
self.diffableSnapshot.moveSection(sectionID, afterSection: afterSectionID)
|
||||
}
|
||||
|
||||
/**
|
||||
Moves a section at a specified index to a new index
|
||||
|
||||
- parameter sectionIndex: a section index in the list to move. Specifying an invalid value will raise an exception.
|
||||
- parameter newSectionIndex: the new section index to move into. Specifying an invalid value will raise an exception.
|
||||
*/
|
||||
public mutating func moveSection(at sectionIndex: Int, to newSectionIndex: Int) {
|
||||
|
||||
self.diffableSnapshot.unsafeMoveSection(at: sectionIndex, to: newSectionIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
Marks the specified sections as reloaded
|
||||
|
||||
- parameter sectionIDs: the section identifiers to reload
|
||||
*/
|
||||
public mutating func reloadSections<S: Sequence>(withIDs sectionIDs: S) where S.Element == SectionID {
|
||||
public mutating func reloadSections<C: Collection>(withIDs sectionIDs: C) where C.Element == SectionID {
|
||||
|
||||
self.diffableSnapshot.reloadSections(sectionIDs)
|
||||
}
|
||||
|
||||
/**
|
||||
Marks the specified section indices as reloaded
|
||||
|
||||
- parameter sectionIndices: the section indices to reload. Specifying an invalid value will raise an exception.
|
||||
*/
|
||||
public mutating func reloadSections<C: Collection>(at sectionIndices: C) where C.Element == Int {
|
||||
|
||||
self.diffableSnapshot.unsafeReloadSections(at: sectionIndices)
|
||||
}
|
||||
|
||||
|
||||
// MARK: RandomAccessCollection
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#if canImport(Combine)
|
||||
|
||||
import Combine
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - ObjectPublisher
|
||||
|
||||
@@ -135,8 +135,19 @@ extension ObjectPublisher {
|
||||
|
||||
func cancel() {
|
||||
|
||||
self.publisher.removeObserver(self)
|
||||
self.subscriber = nil
|
||||
|
||||
if Thread.isMainThread {
|
||||
|
||||
self.publisher.removeObserver(self)
|
||||
}
|
||||
else {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
self.publisher.removeObserver(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user