Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uses native implementation when available #43

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB762CB22B455170050DC03"
BuildableName = "DiffableDataSources.framework"
BlueprintName = "DiffableDataSources"
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
Expand All @@ -39,17 +48,6 @@
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6BB762CB22B455170050DC03"
BuildableName = "DiffableDataSources.framework"
BlueprintName = "DiffableDataSources"
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
Expand All @@ -70,8 +68,6 @@
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand Down
105 changes: 104 additions & 1 deletion Sources/DiffableDataSourceSnapshot.swift
Original file line number Diff line number Diff line change
@@ -1,28 +1,71 @@
import UIKit
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this change also works on AppKit? 🤔

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that would make sense to import either UIKit/AppKit conditionally. As NSDiffableDataSourceSnapshot seems compatible with both.


/// A class for backporting `NSDiffableDataSourceSnapshot` introduced in iOS 13.0+, macOS 10.15+, tvOS 13.0+.
/// Represents the mutable state of diffable data source of UI.
public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable> {
internal var structure = SnapshotStructure<SectionIdentifierType, ItemIdentifierType>()

private let forceFallback: Bool
private var _nativeSnapshot: Any?
@available(iOS 13.0, *)
internal var nativeSnapshot: NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> {
get {
return _nativeSnapshot as! NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>
}
set {
_nativeSnapshot = newValue
}
}

/// Creates a new empty snapshot object.
public init() {}
public init() {
self.init(forceFallback: false)
}

internal init(forceFallback: Bool) {
self.forceFallback = forceFallback
if #available(iOS 13.0, *), !forceFallback {
nativeSnapshot = .init()
return
}
}

@available(iOS 13.0, *)
static func from(nativeSnapshot: NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>) -> Self {
var snapshot = DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>()
snapshot.nativeSnapshot = nativeSnapshot
return snapshot
}

/// The number of item identifiers in the snapshot.
public var numberOfItems: Int {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.numberOfItems
}
return itemIdentifiers.count
}

/// The number of section identifiers in the snapshot.
public var numberOfSections: Int {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.numberOfSections
}
return sectionIdentifiers.count
}

/// All section identifiers in the snapshot.
public var sectionIdentifiers: [SectionIdentifierType] {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.sectionIdentifiers
}
return structure.allSectionIDs
}

/// All item identifiers in the snapshot.
public var itemIdentifiers: [ItemIdentifierType] {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.itemIdentifiers
}
return structure.allItemIDs
}

Expand All @@ -33,6 +76,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
///
/// - Returns: The number of item identifiers in the specified section.
public func numberOfItems(inSection identifier: SectionIdentifierType) -> Int {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.numberOfItems(inSection: identifier)
}
return itemIdentifiers(inSection: identifier).count
}

Expand All @@ -43,6 +89,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
///
/// - Returns: The item identifiers in the specified section.
public func itemIdentifiers(inSection identifier: SectionIdentifierType) -> [ItemIdentifierType] {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.itemIdentifiers(inSection: identifier)
}
return structure.items(in: identifier)
}

Expand All @@ -53,6 +102,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
///
/// - Returns: A section identifier containing the specified item.
public func sectionIdentifier(containingItem identifier: ItemIdentifierType) -> SectionIdentifierType? {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.sectionIdentifier(containingItem: identifier)
}
return structure.section(containing: identifier)
}

Expand All @@ -63,6 +115,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
///
/// - Returns: An index of the specified item.
public func indexOfItem(_ identifier: ItemIdentifierType) -> Int? {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.indexOfItem(identifier)
}
return itemIdentifiers.firstIndex { $0.isEqualHash(to: identifier) }
}

Expand All @@ -73,6 +128,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
///
/// - Returns: An index of the specified section.
public func indexOfSection(_ identifier: SectionIdentifierType) -> Int? {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.indexOfSection(identifier)
}
return sectionIdentifiers.firstIndex { $0.isEqualHash(to: identifier) }
}

Expand All @@ -82,6 +140,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - identifiers: The item identifiers to be appended.
/// - sectionIdentifier: An identifier of section to append the given identiciers.
public mutating func appendItems(_ identifiers: [ItemIdentifierType], toSection sectionIdentifier: SectionIdentifierType? = nil) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.appendItems(identifiers, toSection: sectionIdentifier)
}
structure.append(itemIDs: identifiers, to: sectionIdentifier)
}

Expand All @@ -91,6 +152,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - identifiers: The item identifiers to be inserted.
/// - beforeIdentifier: An identifier of item.
public mutating func insertItems(_ identifiers: [ItemIdentifierType], beforeItem beforeIdentifier: ItemIdentifierType) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.insertItems(identifiers, beforeItem: beforeIdentifier)
}
structure.insert(itemIDs: identifiers, before: beforeIdentifier)
}

Expand All @@ -100,6 +164,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - identifiers: The item identifiers to be inserted.
/// - afterIdentifier: An identifier of item.
public mutating func insertItems(_ identifiers: [ItemIdentifierType], afterItem afterIdentifier: ItemIdentifierType) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.insertItems(identifiers, afterItem: afterIdentifier)
}
structure.insert(itemIDs: identifiers, after: afterIdentifier)
}

Expand All @@ -108,11 +175,17 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - Parameters:
/// - identifiers: The item identifiers to be deleted.
public mutating func deleteItems(_ identifiers: [ItemIdentifierType]) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.deleteItems(identifiers)
}
structure.remove(itemIDs: identifiers)
}

/// Deletes the all items in the snapshot.
public mutating func deleteAllItems() {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.deleteAllItems()
}
structure.removeAllItems()
}

Expand All @@ -122,6 +195,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - identifier: An item identifier to be moved.
/// - toIdentifier: An identifier of item.
public mutating func moveItem(_ identifier: ItemIdentifierType, beforeItem toIdentifier: ItemIdentifierType) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.moveItem(identifier, beforeItem: toIdentifier)
}
structure.move(itemID: identifier, before: toIdentifier)
}

Expand All @@ -131,6 +207,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - identifier: An item identifier to be moved.
/// - toIdentifier: An identifier of item.
public mutating func moveItem(_ identifier: ItemIdentifierType, afterItem toIdentifier: ItemIdentifierType) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.moveItem(identifier, afterItem: toIdentifier)
}
structure.move(itemID: identifier, after: toIdentifier)
}

Expand All @@ -139,6 +218,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - Parameters:
/// - identifiers: The item identifiers to be reloaded.
public mutating func reloadItems(_ identifiers: [ItemIdentifierType]) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.reloadItems(identifiers)
}
structure.update(itemIDs: identifiers)
}

Expand All @@ -147,6 +229,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - Parameters:
/// - identifiers: The section identifiers to be appended.
public mutating func appendSections(_ identifiers: [SectionIdentifierType]) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.appendSections(identifiers)
}
structure.append(sectionIDs: identifiers)
}

Expand All @@ -156,6 +241,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - identifiers: The section identifiers to be inserted.
/// - toIdentifier: An identifier of setion.
public mutating func insertSections(_ identifiers: [SectionIdentifierType], beforeSection toIdentifier: SectionIdentifierType) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.insertSections(identifiers, beforeSection: toIdentifier)
}
structure.insert(sectionIDs: identifiers, before: toIdentifier)
}

Expand All @@ -165,6 +253,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - identifiers: The section identifiers to be inserted.
/// - toIdentifier: An identifier of setion.
public mutating func insertSections(_ identifiers: [SectionIdentifierType], afterSection toIdentifier: SectionIdentifierType) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.insertSections(identifiers, afterSection: toIdentifier)
}
structure.insert(sectionIDs: identifiers, after: toIdentifier)
}

Expand All @@ -173,6 +264,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - Parameters:
/// - identifiers: The section identifiers to be deleted.
public mutating func deleteSections(_ identifiers: [SectionIdentifierType]) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.deleteSections(identifiers)
}
structure.remove(sectionIDs: identifiers)
}

Expand All @@ -182,6 +276,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - identifier: A section identifier to be moved.
/// - toIdentifier: An identifier of section.
public mutating func moveSection(_ identifier: SectionIdentifierType, beforeSection toIdentifier: SectionIdentifierType) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.moveSection(identifier, beforeSection: toIdentifier)
}
structure.move(sectionID: identifier, before: toIdentifier)
}

Expand All @@ -191,6 +288,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - identifier: A section identifier to be moved.
/// - toIdentifier: An identifier of section.
public mutating func moveSection(_ identifier: SectionIdentifierType, afterSection toIdentifier: SectionIdentifierType) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.moveSection(identifier, afterSection: toIdentifier)
}
structure.move(sectionID: identifier, after: toIdentifier)
}

Expand All @@ -199,6 +299,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
/// - Parameters:
/// - identifiers: The section identifiers to be reloaded.
public mutating func reloadSections(_ identifiers: [SectionIdentifierType]) {
if #available(iOS 13.0, *), !forceFallback {
return nativeSnapshot.reloadSections(identifiers)
}
structure.update(sectionIDs: identifiers)
}
}
4 changes: 2 additions & 2 deletions Sources/Internal/DiffableDataSourceCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ final class DiffableDataSourceCore<SectionIdentifierType: Hashable, ItemIdentifi
}
}

func snapshot() -> DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> {
var snapshot = DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>()
func snapshot(forceFallback: Bool) -> DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> {
var snapshot = DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>(forceFallback: forceFallback)
snapshot.structure.sections = currentSnapshot.structure.sections
return snapshot
}
Expand Down
Loading