I am maintaining a legacy code base which will use SwiftUI. I am using the new refreshable api: Apple Developer Documentation. It is a bit annoying that they force you to use async await, since I have a part of refreshing code which can NOT be turned fully async await.
The reason I can not use async await for this code, is because the the application sends and receives messages over a websocket . The application manually matches the responses to the requests and than call the closure when they arrive. I don't believe this is possible to completely rewrite to async await.
I have a closure which eventually will always return a result. When that result have arrived, the spinner should go away. This is my horrible async await wrapper (simplified):
/// Terrible way of adding async await support
func sendAsync() async {
try! await Task {
var future: Void? = nil
self.onReceive = { _ in
future = ()
}
while true {
if future != nil {
return
}
// This is 10 ms
try await Task.sleep(nanoseconds: 10_000_000)
}
}.value
}
So this is a spinlock based async await wrapper. I was wondering if there is a better way to do it. I wrapped in inside a Task
, it won't run on the main thread that way.
Is there some existing async await wrapper which waits for a value to be non-nil and then wakes up? Is there a different api for refreshable
which does not require async await?