Search code examples
iosswiftswiftuiconcurrency

Fixing warnings of non-conformance to "Sendable" for ImageResource in Swift 5.10


I have a file with some constants that maps enums to associated ImageResource for simplified usage in other places. Sample is below

  static let imagePreviews: [MyEnum: ImageResource] = [
    .Enum1: .imageResource1,
    .Enum1: .imageResource2,
    ...
  ]

After upgrading to latest XCode that uses Swift 5.10 following warning is shown around code block above and judging by other similar warnings, common pattern is usage of ImageResource

Static property 'activityBlockImagePreviews' is not concurrency-safe because it is not either conforming to 'Sendable' or isolated to a global actor; this is an error in Swift 6


Solution

  • The issue is that you have a static (or a global) that represents an unsynchronized, shared mutable state. If this was your own type, you could make it Sendable. (See WWDC 2022 video Eliminate data races using Swift Concurrency.)

    But I presume you are using the framework’s ImageResource type, which is not Sendable. So, you can get around this lack of sendability of the underlying type by synchronizing your interaction with your properties. You can achieve this with a global actor. E.g., if you wanted to isolate it to the main actor:

    @MainActor
    extension ImageResource {
        static let imageResource1 = ImageResource(name: "foo", bundle: .main)
        static let imageResource2 = ImageResource(name: "bar", bundle: .main)
    }
    

    And then:

    @MainActor
    static let imagePreviews: [MyEnum: ImageResource] = [
        .foo: .imageResource1,
        .bar: .imageResource2
    ]