Concurrency: How to update UIKit Views from Sendable Closures? (with data race checks enabled)

I came across this post and tried to build my project with data race checks enabled. In a UIViewController I get a warning because I try to update another UIViewController (non-Sendable reference Type) in a detached Task (@Sendable Closure).

private func preloadTileImages() {
    Task.detached(priority: .background) { [self] in
        // Rendering of the both UIImages take some seconds, so I perform it in the background
        let standard = UIImage(named: "map-default")!.prerender()
        let sattelite = UIImage(named: "map-satellite")!.prerender()
        await MainActor.run { [bottomSheet] in // Cannot use property 'bottomSheet' with a non-sendable type 'MapSelectionViewController' across actors
            bottomSheet.standardMapImage = standard // Cannot use let 'standard' with a non-sendable type 'UIImage' from concurrently-executed code
            bottomSheet.satteliteImage = sattelite // Cannot use let 'sattelite' with a non-sendable type 'UIImage' from concurrently-executed code
        }
    }
}

How am I supposed to update the UI from @Sendable-closures using the new concurrency feature?

The project was built using -Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks flags.

Can you use @preconcurrency import UIKit (in Xcode 13.3)? This is why you shouldn't build with these settings on all the time: the underlying frameworks haven't been updated to properly work with the system. So these build settings are really just something you'd want to turn on to check things with rather than build with all the time. This is also why most of these checks have been turned off for Swift 5.6 / Xcode 13.3. If you really want to build with those settings, you should really use that newer version of Swift (hopefully the final version will be out this week or next), as the diagnostics have improved.

1 Like

Hi @Jon_Shier, thank you for your reply. @preconcurrency silences the warning for now.
Just out of curiosity: Can I expect classes isolated to the MainActor are also eligible to conform to Sendable, because the actor handles its synchronization? This way I would expect UIKit Views may be MainActor isolated and Sendable in some future iOS update.

I'm still trying to understand actor isolation. Thanks again for your help :slight_smile:

I don't really know if actor isolation is supposed to imply Sendable for classes or not. I need to update my thread on sendability, so maybe there's something there.