Skip to content

Commit 6c52773

Browse files
authoredAug 23, 2023
Async data storing (#10)
1 parent 750645d commit 6c52773

File tree

4 files changed

+31
-33
lines changed

4 files changed

+31
-33
lines changed
 

‎Sources/DataStore/DataStore.swift

+10-14
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ open class DataStore<DataLoader: DataLoading>: ConsumingObservableObject, DataSt
6363

6464
- Note: This method iterates through the data and sets each value in the cache using its ID as the key.
6565
*/
66-
open func store(data: [DeviceData]) throws {
66+
@MainActor
67+
open func store(data: [DeviceData]) async throws {
6768
for datum in data {
6869
cache.set(value: datum, forKey: datum.id)
6970
}
@@ -79,7 +80,8 @@ open class DataStore<DataLoader: DataLoading>: ConsumingObservableObject, DataSt
7980

8081
- Note: This method iterates through the IDs and removes each value from the cache.
8182
*/
82-
open func delete(data: [DeviceData.ID]) throws {
83+
@MainActor
84+
open func delete(data: [DeviceData.ID]) async throws {
8385
for datum in data {
8486
cache.remove(datum)
8587
}
@@ -92,7 +94,7 @@ open class DataStore<DataLoader: DataLoading>: ConsumingObservableObject, DataSt
9294

9395
- Note: This method retrieves all the values from the cache and returns them as an array.
9496
*/
95-
open func fetch() -> [DeviceData] {
97+
open func fetch() async -> [DeviceData] {
9698
Array(cache.allValues.values)
9799
}
98100

@@ -106,8 +108,8 @@ open class DataStore<DataLoader: DataLoading>: ConsumingObservableObject, DataSt
106108

107109
- Note: This method filters the fetched data using the given filter closure and returns the filtered results.
108110
*/
109-
open func fetch(where filter: (DeviceData) -> Bool) -> [DeviceData] {
110-
let allValues = fetch()
111+
open func fetch(where filter: (DeviceData) -> Bool) async -> [DeviceData] {
112+
let allValues = await fetch()
111113

112114
let filteredValues = allValues.filter(filter)
113115

@@ -126,7 +128,7 @@ open class DataStore<DataLoader: DataLoading>: ConsumingObservableObject, DataSt
126128

127129
- Note: This method resolves the ID to the corresponding value in the cache.
128130
*/
129-
open func fetch(id: DeviceData.ID) throws -> DeviceData {
131+
open func fetch(id: DeviceData.ID) async throws -> DeviceData {
130132
try cache.resolve(id, as: DeviceData.self)
131133
}
132134

@@ -139,10 +141,7 @@ open class DataStore<DataLoader: DataLoading>: ConsumingObservableObject, DataSt
139141
*/
140142
open func load() async throws {
141143
let loadedData: [DeviceData] = try await loader.load()
142-
143-
try await MainActor.run {
144-
try store(data: loadedData)
145-
}
144+
try await store(data: loadedData)
146145
}
147146

148147
/**
@@ -157,10 +156,7 @@ open class DataStore<DataLoader: DataLoading>: ConsumingObservableObject, DataSt
157156
*/
158157
open func load(id: DeviceData.ID) async throws {
159158
let loadedData: DeviceData = try await loader.load(id: id)
160-
161-
try await MainActor.run {
162-
try store(data: [loadedData])
163-
}
159+
try await store(data: [loadedData])
164160
}
165161
}
166162

‎Sources/DataStore/Protocols/DataStoring.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,24 @@ public protocol DataStoring {
88

99
/// Stores an array of `DeviceData` objects.
1010
/// - Parameter data: The data to store or update.
11-
func store(data: [DeviceData]) throws
11+
func store(data: [DeviceData]) async throws
1212

1313
/// Deletes an array of `DeviceData` objects based on their identifiers.
1414
/// - Parameter data: The identifiers of the data to delete.
15-
func delete(data: [DeviceData.ID]) throws
15+
func delete(data: [DeviceData.ID]) async throws
1616

1717
/// Fetches all stored `DeviceData` objects.
1818
/// - Returns: An array of fetched device-specific data.
19-
func fetch() -> [DeviceData]
19+
func fetch() async -> [DeviceData]
2020

2121
/// Fetches stored `DeviceData` objects that satisfy the given filter predicate.
2222
/// - Parameter where: A closure that takes a `DeviceData` object and returns a Boolean value indicating whether the object should be included in the result.
2323
/// - Returns: An array of fetched device-specific data that pass the filter.
24-
func fetch(where filter: (DeviceData) -> Bool) -> [DeviceData]
24+
func fetch(where filter: (DeviceData) -> Bool) async -> [DeviceData]
2525

2626
/// Fetches a single stored `DeviceData` object based on its identifier.
2727
/// - Parameter id: The identifier of the data to fetch.
2828
/// - Returns: The fetched device-specific data.
2929
/// - Throws: An error if the data could not be found.
30-
func fetch(id: DeviceData.ID) throws -> DeviceData
30+
func fetch(id: DeviceData.ID) async throws -> DeviceData
3131
}

‎Tests/DataStoreTests/DataStoreSubscriptTests.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ final class DataStoreSubscriptTests: XCTestCase {
77

88
try await store.load()
99

10-
let values = store.fetch()
10+
let values = await store.fetch()
1111

1212
XCTAssertEqual(values.count, 3)
1313

@@ -23,7 +23,7 @@ final class DataStoreSubscriptTests: XCTestCase {
2323

2424
try await store.load()
2525

26-
let values = store.fetch()
26+
let values = await store.fetch()
2727

2828
XCTAssertEqual(values.count, 3)
2929

@@ -41,7 +41,7 @@ final class DataStoreSubscriptTests: XCTestCase {
4141

4242
try await store.load()
4343

44-
let values = store.fetch()
44+
let values = await store.fetch()
4545

4646
XCTAssertEqual(values.count, 3)
4747

@@ -57,7 +57,7 @@ final class DataStoreSubscriptTests: XCTestCase {
5757

5858
try await store.load()
5959

60-
let values = store.fetch()
60+
let values = await store.fetch()
6161

6262
XCTAssertEqual(values.count, 3)
6363

@@ -79,7 +79,7 @@ final class DataStoreSubscriptTests: XCTestCase {
7979

8080
try await store.load()
8181

82-
let values = store.fetch()
82+
let values = await store.fetch()
8383

8484
XCTAssertEqual(values.count, 3)
8585

‎Tests/DataStoreTests/DataStoreTests.swift

+11-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ final class DataStoreTests: XCTestCase {
88

99
try await store.load()
1010

11-
let values = store.fetch()
11+
let values = await store.fetch()
1212

1313
XCTAssertEqual(values.count, 3)
1414
}
@@ -20,7 +20,7 @@ final class DataStoreTests: XCTestCase {
2020

2121
try await store.load(id: expectedID)
2222

23-
let value = try store.fetch(id: expectedID)
23+
let value = try await store.fetch(id: expectedID)
2424

2525
XCTAssertEqual(value.id, expectedID)
2626
}
@@ -30,7 +30,7 @@ final class DataStoreTests: XCTestCase {
3030

3131
try await store.load()
3232

33-
let values = store.fetch { data in
33+
let values = await store.fetch { data in
3434
data.color == Color(red: 0, green: 1, blue: 0)
3535
}
3636

@@ -40,7 +40,7 @@ final class DataStoreTests: XCTestCase {
4040
func testStoreAndFetch() async throws {
4141
let store = DataStore(loader: TestDataLoader())
4242

43-
let values = store.fetch()
43+
let values = await store.fetch()
4444

4545
XCTAssertEqual(values.count, 0)
4646

@@ -49,7 +49,7 @@ final class DataStoreTests: XCTestCase {
4949
let expectedColor = Color.green
5050
let expectedEnumValue = TestDeviceData.DeviceEnum.weirdCaseExample
5151

52-
try store.store(
52+
try await store.store(
5353
data: [
5454
TestDeviceData(
5555
id: expectedID,
@@ -60,7 +60,7 @@ final class DataStoreTests: XCTestCase {
6060
]
6161
)
6262

63-
let value = try store.fetch(id: expectedID)
63+
let value = try await store.fetch(id: expectedID)
6464

6565
XCTAssertEqual(value.id, expectedID)
6666
XCTAssertEqual(value.userName, expectedUserName)
@@ -73,12 +73,14 @@ final class DataStoreTests: XCTestCase {
7373

7474
try await store.load()
7575

76-
let values = store.fetch()
76+
let values = await store.fetch()
7777

7878
XCTAssertEqual(values.count, 3)
7979

80-
try store.delete(data: values.map(\.id))
80+
try await store.delete(data: values.map(\.id))
8181

82-
XCTAssertEqual(store.fetch().count, 0)
82+
let fetchCount = await store.fetch().count
83+
84+
XCTAssertEqual(fetchCount, 0)
8385
}
8486
}

0 commit comments

Comments
 (0)
Please sign in to comment.