Swift async/await what it the alternative of DispatchQueue.important.async

You requested:
Can I nonetheless use
DispatchQueue.important.async
?
If you’re in an async
technique and need to dispatch one thing to the primary queue, probably the most literal equal can be:
MainActor.run { ... }
However it’s extra prudent to easily mark the strategy (or its class) with @MainActor
. Not solely will this be sure that it runs it on the primary thread, however you get compile-time warnings should you try to name it from the flawed actor.
So, in case your view mannequin is marked with @MainActor
, the guide operating of the duty on the MainActor
turns into pointless. That is very true when coping with revealed properties of an noticed object.
For instance, contemplate:
@MainActor
class ViewModel: ObservableObject {
@Printed var values: [Int] = []
func fetchData() async {
let foo = await ...
values = foo.values
}
}
After which
struct ContentView: View {
@ObservedObject var viewModel = ViewModel()
var physique: some View {
Checklist {
...
}
.refreshable {
await viewModel.fetchData()
}
}
}
(Observe, I made fetchData
an async
technique and await
it inside refreshable
in order that the spinner precisely displays when the async
course of is operating.)
See WWDC 2021 video Swift concurrency: Replace a pattern app. That’s admittedly illustrating the transition of a UIKit app, however consists of examples of @MainActor
and MainActor.run
.
Observe, whereas @MainActor
, largely eliminates the necessity for MainActor.run { … }
, there are nonetheless some situations the place you may use this run
sample. Particularly, if you’re on another actor and need to run, for instance, three separate @MainActor
features in succession on the primary thread, you possibly can wrap the sequence of them inside a single MainActor.run { … }
block, thereby operating all three with a single dispatch to the primary actor, slightly than three separate calls.
Above, I targeted on the salient parts, however right here is my full MCVE:
struct ContentView: View {
@ObservedObject var viewModel = ViewModel()
var physique: some View {
Checklist {
ForEach(viewModel.values, id: .self) { worth in
Textual content("(worth)")
}
}
.refreshable {
await viewModel.fetchData()
}
}
}
struct Foo: Decodable{
let json: [Int]
}
@MainActor
class ViewModel: ObservableObject {
@Printed var values: [Int] = []
func fetchData() async {
do {
let foo = strive await object(Foo.self, for: request)
values = foo.json
} catch {
print(error)
}
}
func object<T: Decodable>(_ sort: T.Kind, for request: URLRequest) async throws -> T {
let (information, response) = strive await URLSession.shared.information(for: request)
guard let response = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
guard 200 ... 299 ~= response.statusCode else {
throw ApiError.failure(response.statusCode, information)
}
return strive JSONDecoder().decode(T.self, from: information)
}
var request: URLRequest = {
let url = URL(string: "https://httpbin.org/something")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = "[1,2,3,4,5]".information(utilizing: .utf8)
request.addValue("utility/json", forHTTPHeaderField: "Content material-Kind")
request.addValue("utility/json", forHTTPHeaderField: "Settle for")
return request
}()
}
enum ApiError: Error {
case failure(Int, Knowledge)
}
Credit: www.ismmailgsm.com