Actor URLSession Warning?

Non-sendable type '(any URLSessionTaskDelegate)?' exiting actor-isolated context in call to non-isolated instance method 'data(from:delegate:)' cannot cross actor boundary

Please help, I am 1000% stuck on this issue in particular. Using strict asynchronous warnings, how can I make this work without warning? I can convert NetworkManager into a struct, but I prefer to keep it as an actor so that it is Sendable by default.

Replies

This is a bug in Swift. Until it's fixed you can work around it by changing import Foundation to @preconcurrency import Foundation.

See this Swift forum thread.

For what it’s worth, I get around this with a rendition that doesn’t take a delegate parameter, cutting the Gordian knot:

extension URLSession {
    public nonisolated func download(with url: URL) async throws -> (URL, URLResponse) {
        try await download(from: url)
    }
}

Still happens in Xcode 15b6

Nonisolated Extension Functions

I liked  @eoonline's solution.

This is a variation of his solution for the data(for:) and data(from:) functions:

extension URLSession {
    public nonisolated func getData(for request: URLRequest) async throws -> (Data, URLResponse) {
        try await data(for: request)
    }

    public nonisolated func getData(for url: URL) async throws -> (Data, URLResponse) {
        try await data(from: url)
    }
}

What is nonisolated?

This means the function can be called OUTSIDE the actor's isolated domain.

Is it safe?

Yes, nonisolated methods should typically be ‘read-only’ and not modify any state.

In this case, since the getData functions are just performing a network request and not modifying any state, it’s safe to make them nonisolated.