Suppose you have a method that executes asynchronously in a global context. Depending on the execution you need to update the UI.
private func fetchUser() async {
do {
let user = try await authService.fetchCurrentUser()
view.setUser(user)
} catch {
if let error = error {
view.showError(message: error.message)
}
}
}
Where is the correct place to switch to the main thread?
- Assign
@MainActorto thefetchUser()method:
@MainActor
private func fetchUser() async {
...
}
- Assign
@MainActorto thesetUser(_ user: User)andshowError(message: String)view's methods:
class SomePresenter {
private func fetchUser() async {
do {
let user = try await authService.fetchCurrentUser()
await view.setUser(user)
} catch {
if let error = error {
await view.showError(message: error.message)
}
}
}
}
class SomeViewController: UIViewController {
@MainActor
func setUser(_ user: User) {
...
}
@MainActor
func showError(message: String) {
...
}
}
- Do not assign
@MainActor. Useawait MainActor.runorTaskwith@MainActorinstead to runsetUser(_ user: User)andshowError(message: String)on the main thread (likeDispatchQueue.main.async):
private func fetchUser() async {
do {
let user = try await authService.fetchCurrentUser()
await MainActor.run {
view.setUser(user)
}
} catch {
if let error = error {
await MainActor.run {
view.showError(message: error.message)
}
}
}
}