Skip to content

Commit a0f23d6

Browse files
committed
Fix demo crash when deleting SwiftData discoveries on device
Route store writes through Task.detached so MainActor-inherited tasks do not run SwiftData mutations on the main thread. Delete by fetching in the actor's ModelContext instead of model(for:) with IDs from @query.
1 parent daa5601 commit a0f23d6

2 files changed

Lines changed: 28 additions & 9 deletions

File tree

Demo/ReliaBLE Demo/ReliaBLE Demo/Central/CentralViewModel.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,24 @@ import ReliaBLE
6666
}
6767

6868
func clearAllData() {
69-
Task { await deviceStore?.clearAll() }
69+
guard let deviceStore else { return }
70+
Task.detached {
71+
await deviceStore.clearAll()
72+
}
7073
}
7174

7275
func deleteDiscoveries(ids: [PersistentIdentifier]) {
73-
Task { await deviceStore?.deleteDiscoveries(ids: ids) }
76+
guard let deviceStore else { return }
77+
Task.detached {
78+
await deviceStore.deleteDiscoveries(ids: ids)
79+
}
7480
}
7581

7682
func deleteDevices(ids: [PersistentIdentifier]) {
77-
Task { await deviceStore?.deleteDevices(ids: ids) }
83+
guard let deviceStore else { return }
84+
Task.detached {
85+
await deviceStore.deleteDevices(ids: ids)
86+
}
7887
}
7988

8089
private func parseServices(from input: String) -> [CBUUID]? {

Demo/ReliaBLE Demo/ReliaBLE Demo/Central/DeviceStoreActor.swift

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,24 +103,34 @@ actor DeviceStoreActor: ModelActor {
103103

104104
func deleteDiscoveries(ids: [PersistentIdentifier]) {
105105
assertWritesOffMainThread()
106+
guard !ids.isEmpty else { return }
106107

107-
for id in ids {
108-
if let event = modelContext.model(for: id) as? DiscoveryEvent {
108+
let idSet = Set(ids)
109+
do {
110+
let events = try modelContext.fetch(FetchDescriptor<DiscoveryEvent>())
111+
for event in events where idSet.contains(event.persistentModelID) {
109112
modelContext.delete(event)
110113
}
114+
try modelContext.save()
115+
} catch {
116+
print("Failed to delete discoveries: \(error)")
111117
}
112-
try? modelContext.save()
113118
}
114119

115120
func deleteDevices(ids: [PersistentIdentifier]) {
116121
assertWritesOffMainThread()
122+
guard !ids.isEmpty else { return }
117123

118-
for id in ids {
119-
if let device = modelContext.model(for: id) as? Device {
124+
let idSet = Set(ids)
125+
do {
126+
let devices = try modelContext.fetch(FetchDescriptor<Device>())
127+
for device in devices where idSet.contains(device.persistentModelID) {
120128
modelContext.delete(device)
121129
}
130+
try modelContext.save()
131+
} catch {
132+
print("Failed to delete devices: \(error)")
122133
}
123-
try? modelContext.save()
124134
}
125135

126136
private func assertWritesOffMainThread() {

0 commit comments

Comments
 (0)