Search code examples
swiftswiftuiasync-awaitswiftui-list

Using TaskGroup for removing entries from persisted store when interacting with SwiftUI List


I have a SwiftUI List where removal is enabled.

.onDelete modifier applied to ForEach accepts an IndexSet.

.onDelete { indexSet in
    viewModel.remove(indexSet: IndexSet)
}

On the contrary, the store where the items are saved can deal with just one item removal at the time. The view model invoked from the view that contains the List and that performs the removal has been coded like the following:

func remove(indexSet: IndexSet) async throws {
    let items = await store.items

    return try await withThrowingTaskGroup(of: Void.self) { group in
        for index in indexSet {
            group.addTask {
                let item = items[index]
                try await self.store.remove(item)
            }
        }
        
        try await group.waitForAll()
    }
}

Do you think that leveraging TaskGroup is the best way to accomplish deletion of an item once at the time?


Solution

  • TaskGroup does the opposite, it performs multiple tasks concurrently.

    Just remove the items with a standard loop, however iterate the indices backwards to avoid index chaos.

    func remove(indexSet: IndexSet) async throws {
        let items = await store.items
        for index in indexSet.reversed() {
            let item = items[index]
            try await self.store.remove(item)
        }
    }
    

    I recommend also to check if the last index of the index set is less than the number of items in the array for example

    guard !indexSet.isEmpty, indexSet.last! < items.count else { return }