Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 6 - Switch from @MainActor func to async function

How can I call in Swift 6 a normal async function from a MainActor function? I do not want to execute URLRequests on the MainThread

I want to switch from the Main Thread to an async Thread but I have no idea how to do it... This code doesn't work and throws the following error: Sending 'self.service' risks causing data races

import SwiftUI

struct CustomView: View {
    private let viewModel: CustomViewModel = CustomViewModel()

    var body: some View {
        Text("HELLO")
            .task {
                Task {
                    await viewModel.getDataFromBackend()
                }
            }
    }
}

@Observable
final class CustomViewModel {
    private let service: CustomService = DefaultCustomService()

    @MainActor func getDataFromBackend() async {
        // Updating UI on Main-Thread

        // This shouldn't run on the Main Thread!
        await service.provideBackendData()
    }
}


protocol CustomService {
    func provideBackendData() async
}

struct DefaultCustomService: CustomService {
    func provideBackendData() async {
        // Async Stuff which shouldn't run on Main-Thread
    }
}
like image 869
Godlike Avatar asked Nov 20 '25 19:11

Godlike


1 Answers

You can just add

protocol CustomService: Sendable {

To remove the error.

In order to safely make something Sendable you should meet all of these official requirements

  • Value types
  • Reference types with no mutable storage
  • Reference types that internally manage access to their state
  • Functions and closures (by marking them with @Sendable)

https://developer.apple.com/documentation/swift/sendable

Unofficially any reference types should also be marked final so the user cant create unsafe mutating children.

You can also use actor and globalActor to make something Sendable.

like image 135
lorem ipsum Avatar answered Nov 22 '25 09:11

lorem ipsum



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!