I have a large project with mixed C++, Objective-C, and Swift. I'm starting to enable strict concurrency checking to iron out as many errors I can ahead of Swift 6's release, and I'm running into a warning about a network utility method I have in Objective-C that fetches data from a URL and returns the result as a JSON dictionary.
actor Foo {
func fetch() async {
let url = URL(string: "https://www.olivetree.com")!
let jsonData = await NetworkUtil.fetchJson(from: url)
//do stuff with json
}
}
I get this warning from the call to fetchJson:
Non-sendable type '[AnyHashable : Any]?' returned by implicitly asynchronous call to nonisolated function cannot cross actor boundary
I think I understand why this warning exists - the contents of this NSDictionary could be anything and it therefore can't be verified to be Sendable, so it can't safely cross the threading boundary. But in this case I think it actually is safe, because it's not being used by the fetchJson method after the call completes.
I've managed to solve this by having the fetchJson method return the Data / NSData directly and do the json parse in the caller, but that's a little awkward. And I should note that the reason it's in Objective-C is that in my actual project it calls through to some C++ network code, but I made a test app with exactly the code above and still got the warning.
If that proposal is accepted, you'd be able to annotate that fetchJsonFrom returns a transferring result in the header, so that Swift understands the non-Sendable value can be treated as "disconnected", meaning that no other values are referencing it, so it's safe to pass over the isolation boundary.
Yes, you should be able to write __attribute__((__swift_attr__("transferring"))) on the result type in Objective-C. Of course, the compiler can't validate that for you like it can from Swift.
SE-0430 has been accepted and shipped, and I believe transferring got renamed to sending, and is available to Objective-C via NS_SWIFT_SENDING. But I can't get it to work when I apply it in various ways to the Objective-C method declaration, to mark the dictionary as sending. I've filed a compiler bug: