1

I'm getting a warning with this code and I don't understand how to fix it. I'm curious to know how to pass a function into the task modifier.

private func placeholderRHSView(for client: AppClient) -> some View {
    Color.clear
        .frame(width: 290, height: 290)
        .task(load(client)) // Warning: Converting non-sendable function value to '@Sendable () async -> Void' may introduce data races
}

private func load(_ client: AppClient) -> () -> Void {
    return {
        Task {
            do {
                let apps = try await client.recent()
            } catch {}
        }
    }
}

How should I re-structure this code to make it thread safe?

1 Answer 1

1

First issue is having that floating Task {/*code*/} that isn't thread safe and should not be used without a very good reason and precautions that mimic .task lifecycle behavior.

Now to get a function that can be used directly in .task we have to mimic the signature

func task(priority: TaskPriority = .userInitiated, _ action: @escaping () async -> Void) -> some View

The action is () async -> Void so the function should return that exact type. You are missing the async part.

You also have to add @Sendable which we only know about from warnings

private func load(_ client: AppClient) -> (@Sendable () async -> Void) {

() means that this will be a closure/function so the body will be enclosed with return {/*async code here*/}

private func load(_ client: AppClient) -> (@Sendable () async -> Void) {
   return {
        do {
            let apps = try await client.recent()
            print(apps)
        } catch {
            print(error)
        }
    }
}

Now your View will work as expected.

private func placeholderRHSView(for client: AppClient) -> some View {
    Color.clear
        .frame(width: 290, height: 290)
        .task(load(client))
}

I created a little mock AppClient to make this complie.

struct AppClient{
    func recent() async throws -> String{
        return "recent"
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.