Skip to content

Commit 77c8122

Browse files
committed
Uses native implementation when available
1 parent a457cf6 commit 77c8122

8 files changed

+308
-101
lines changed

DiffableDataSources.xcodeproj/xcshareddata/xcschemes/DiffableDataSources.xcscheme

+9-13
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@
2727
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2828
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
2929
shouldUseLaunchSchemeArgsEnv = "YES">
30+
<MacroExpansion>
31+
<BuildableReference
32+
BuildableIdentifier = "primary"
33+
BlueprintIdentifier = "6BB762CB22B455170050DC03"
34+
BuildableName = "DiffableDataSources.framework"
35+
BlueprintName = "DiffableDataSources"
36+
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
37+
</BuildableReference>
38+
</MacroExpansion>
3039
<Testables>
3140
<TestableReference
3241
skipped = "NO">
@@ -39,17 +48,6 @@
3948
</BuildableReference>
4049
</TestableReference>
4150
</Testables>
42-
<MacroExpansion>
43-
<BuildableReference
44-
BuildableIdentifier = "primary"
45-
BlueprintIdentifier = "6BB762CB22B455170050DC03"
46-
BuildableName = "DiffableDataSources.framework"
47-
BlueprintName = "DiffableDataSources"
48-
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
49-
</BuildableReference>
50-
</MacroExpansion>
51-
<AdditionalOptions>
52-
</AdditionalOptions>
5351
</TestAction>
5452
<LaunchAction
5553
buildConfiguration = "Debug"
@@ -70,8 +68,6 @@
7068
ReferencedContainer = "container:DiffableDataSources.xcodeproj">
7169
</BuildableReference>
7270
</MacroExpansion>
73-
<AdditionalOptions>
74-
</AdditionalOptions>
7571
</LaunchAction>
7672
<ProfileAction
7773
buildConfiguration = "Release"

Sources/DiffableDataSourceSnapshot.swift

+104-1
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,71 @@
1+
import UIKit
2+
13
/// A class for backporting `NSDiffableDataSourceSnapshot` introduced in iOS 13.0+, macOS 10.15+, tvOS 13.0+.
24
/// Represents the mutable state of diffable data source of UI.
35
public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable> {
46
internal var structure = SnapshotStructure<SectionIdentifierType, ItemIdentifierType>()
57

8+
private let forceFallback: Bool
9+
private var _nativeSnapshot: Any?
10+
@available(iOS 13.0, *)
11+
internal var nativeSnapshot: NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> {
12+
get {
13+
return _nativeSnapshot as! NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>
14+
}
15+
set {
16+
_nativeSnapshot = newValue
17+
}
18+
}
19+
620
/// Creates a new empty snapshot object.
7-
public init() {}
21+
public init() {
22+
self.init(forceFallback: false)
23+
}
24+
25+
internal init(forceFallback: Bool) {
26+
self.forceFallback = forceFallback
27+
if #available(iOS 13.0, *), !forceFallback {
28+
nativeSnapshot = .init()
29+
return
30+
}
31+
}
32+
33+
@available(iOS 13.0, *)
34+
static func from(nativeSnapshot: NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>) -> Self {
35+
var snapshot = DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>()
36+
snapshot.nativeSnapshot = nativeSnapshot
37+
return snapshot
38+
}
839

940
/// The number of item identifiers in the snapshot.
1041
public var numberOfItems: Int {
42+
if #available(iOS 13.0, *), !forceFallback {
43+
return nativeSnapshot.numberOfItems
44+
}
1145
return itemIdentifiers.count
1246
}
1347

1448
/// The number of section identifiers in the snapshot.
1549
public var numberOfSections: Int {
50+
if #available(iOS 13.0, *), !forceFallback {
51+
return nativeSnapshot.numberOfSections
52+
}
1653
return sectionIdentifiers.count
1754
}
1855

1956
/// All section identifiers in the snapshot.
2057
public var sectionIdentifiers: [SectionIdentifierType] {
58+
if #available(iOS 13.0, *), !forceFallback {
59+
return nativeSnapshot.sectionIdentifiers
60+
}
2161
return structure.allSectionIDs
2262
}
2363

2464
/// All item identifiers in the snapshot.
2565
public var itemIdentifiers: [ItemIdentifierType] {
66+
if #available(iOS 13.0, *), !forceFallback {
67+
return nativeSnapshot.itemIdentifiers
68+
}
2669
return structure.allItemIDs
2770
}
2871

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

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

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

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

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

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

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

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

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

114184
/// Deletes the all items in the snapshot.
115185
public mutating func deleteAllItems() {
186+
if #available(iOS 13.0, *), !forceFallback {
187+
return nativeSnapshot.deleteAllItems()
188+
}
116189
structure.removeAllItems()
117190
}
118191

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

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

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

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

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

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

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

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

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

@@ -199,6 +299,9 @@ public struct DiffableDataSourceSnapshot<SectionIdentifierType: Hashable, ItemId
199299
/// - Parameters:
200300
/// - identifiers: The section identifiers to be reloaded.
201301
public mutating func reloadSections(_ identifiers: [SectionIdentifierType]) {
302+
if #available(iOS 13.0, *), !forceFallback {
303+
return nativeSnapshot.reloadSections(identifiers)
304+
}
202305
structure.update(sectionIDs: identifiers)
203306
}
204307
}

Sources/Internal/DiffableDataSourceCore.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ final class DiffableDataSourceCore<SectionIdentifierType: Hashable, ItemIdentifi
5151
}
5252
}
5353

54-
func snapshot() -> DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> {
55-
var snapshot = DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>()
54+
func snapshot(forceFallback: Bool) -> DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> {
55+
var snapshot = DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>(forceFallback: forceFallback)
5656
snapshot.structure.sections = currentSnapshot.structure.sections
5757
return snapshot
5858
}

0 commit comments

Comments
 (0)