I’m utilizing Remark and @Observable all through my app, and customarily I do not actually have a necessity for Mix. Nonetheless, I’ve run into conditions the place I want debouncers and throttlers and I do not see different simple answer besides to do it previous means… So, thus the query, trigger I do not know what’s a correct means to do that when utilizing Remark framework.
I did it previous means:
closing class Debouncer: ObservableObject {
personal var cancellables = Set()
personal let tapSubject = PassthroughSubject()
func sendTap(for itemId: String?) {
guard let itemId else { return }
tapSubject.ship(itemId)
}
var handleFavoriteTap: ((String) -> Void)?
init() {
tapSubject
.debounce(for: .milliseconds(300), scheduler: RunLoop.principal)
.sink { [weak self] itemId in
self?.handleFavoriteTap?(itemId)
}
.retailer(in: &cancellables)
}
}
then:
@State personal var debouncer = Debouncer()
and:
.onAppear {
debouncer.handleFavoriteTap = { itemId in
firestoreManager.addFavorite(documentID: itemId)
}
and at last:
.onTapGesture {
debouncer.sendTap(for: merchandise.id)
}
So it really works… Additionally, I kinda did it with AsyncStream (it appears to be working accurately):
@State personal var tapContinuation: AsyncStream.Continuation?
personal func startTapStream() {
let tapStream = AsyncStream { continuation in
self.tapContinuation = continuation
}
Process {
for await itemId in tapStream
.debounce(for: .milliseconds(200))
{
firestoreManager.addFavoriteTip(documentID: itemId)
}
}
}
and:
.onAppear {
startTapStream()
}
However I’m probably not positive which method to take, or if there’s a greater solution to deal with this as a result of there are most likely extra issues I ought to think about in AsyncStream code (e.g., preserving a reference to present faucet activity so I can cancel it on onDisappear…). It simply looks like an excessive amount of problem for a easy debounce, and importing Mix only for it additionally does not sound nice…So what’s a most popular means nowadays for this?