Closed simensol closed 4 years ago
Hello @simensol,
I'm not quite versed in data-flow design in Combine apps, so I won't comment on your setup.
I don't understand how you can get an infinite loop with the removeDuplicates()
modifier.
Can you investigate? Maybe share a stacktrace from inside this infinite loop, hoping it's not totally obfuscated with Combine guts?
Thanks anyway, @groue! I will investigate and follow up.
I didn't managed to fix the cause. By comparing the old Task record to the updated one, the second update in the loop were never executed, hence, breaking the loop:
// ViewModel.swift
@Published var taskStatus: TaskStatus {
didSet {
Task.updateStatus()
}
}
// Tasks.swift
func updateStatus(_ existingTask: Task, newStatus: TaskStatus) throws -> Bool {
_ = try database.write { db in
if var task = try Task.fetchOne(db, key: existingTask.id) {
let isTaskUpdated = try task.updateChanges(db) {
$0.status = newStatus
}
#if DEBUG
if isTaskUpdated {
print("Task.status was updated")
} else {
print("Task.status was not updated")
}
#endif
}
}
}
A more robust solution probably exists. However, I havn't found it (yet).
OK, @simensol. I'd be happy if you could share a reproducible case, so that someone else can keep on investigating (probably me). The sample code you provide is not enough to reproduce the issue and perform adequate debugging.
I will see what I can find, @groue. I'm the only developer on my project, so the git commits are unfortunately a bit messy.
I'm still working on this issue. I think the problem is related to SwiftUI, and not GRDBCombine, but I'm not sure yet. When I initiate the app, 4 TransactionObservation
are created. However, after opening the same View
20 times, the number of TransactionObservation
has increased to 24. I call Cancel()
on the cancellableSet
. Is the increased number of TransactionObservation
expected, or should they be removed when I call Cancel()
on the cancellableSet
? And does the increased number of TransactionObservation
represent an issue?
EDIT:
It seems the issue was related to nested views in SwiftUI. When a view is closed, the subscriber is not automatically canceled. So I have to call Cancel()
on the cancellableSet
manually when a view is closed.
Closing due to lack of activity. See you later in the GRDB repository, because GRDBCombine is no longer an independent library!
I have a
View
with a segmented control picker which is used to update some column namedstatus
in my database.Based on the demo app, I have created the following publisher:
The publisher is used in my
ViewModel
:On initialization, the picker gets its initial value from
@Published var taskStatus
as expected. However, when the picker's value is changed, the following happens:@Published var taskStatus
'sdidSet{}
observes the change, and updates thestatus
column in the database.myPublisher()
observes the change in thestatus
column, and the subscriber is triggered.@Published var taskStatus
is updated, and itsdidSet{}
is fired, updating the database (again).Is it possible to make the publisher (or subscriber) aware of the source of the database update, so that I can break this infinite loop?