How to avoid Swift 6 concurrency warning from UIAccessibility.post()

I have the following var in an @Observable class:

var displayResult: String {
    if let currentResult = currentResult, let decimalResult = Decimal(string: currentResult) {
        let result = decimalResult.formatForDisplay()
            UIAccessibility.post(notification: .announcement, argument: "Current result \(result)")
        return result
    } else {
        return "0"
    }
}

The UIAccessiblity.post gives me this warning:

Reference to static property 'announcement' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

How can I avoid this?

Answered by DTS Engineer in 790860022

You’re not doing anything unsafe here; this problem shows up because the announcement property is a var when, if you were writing this yourself, you would make it a let.

The long-term fix would be for UIKit to make that change. In the short term, the workaround is to apply @preconcurrency to your UIKit import. For example, this code doesn’t issue that warning:

@preconcurrency import UIKit
import Foundation

class MyModel: ObservableObject {
    var displayResult: String {
        let result = "test"
        UIAccessibility.post(notification: .announcement, argument: "Current result \(result)")
        return result
    }
}

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

You’re not doing anything unsafe here; this problem shows up because the announcement property is a var when, if you were writing this yourself, you would make it a let.

The long-term fix would be for UIKit to make that change. In the short term, the workaround is to apply @preconcurrency to your UIKit import. For example, this code doesn’t issue that warning:

@preconcurrency import UIKit
import Foundation

class MyModel: ObservableObject {
    var displayResult: String {
        let result = "test"
        UIAccessibility.post(notification: .announcement, argument: "Current result \(result)")
        return result
    }
}

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for the quick reply and good to know it's not me! (it usually is 😆)

I'm importing SwiftData and SwiftUI, so I tried @preconcurrency import SwiftUI and it does suppress the warning. But I'm new at this and I'm not sure if that's OK or if I should be importing UIKit instead?

Code seems to work so I'm guessing there's a lot of overlap, but I'd like to avoid any unintended side effects down the road.

But I'm new at this

We’re all new at this (-:

I'm not sure if that's OK or if I should be importing UIKit instead?

I don’t think it matters, because in this case your only goal is to suppress the warning. The underlying code is safe.

Which isn’t universally true. Every time you hit a warning like this you have to evaluate whether it’s your issue, an SDK issue, or a compiler issue (the latter being quite rare). That can be quite tricky. I have a couple of great resources to help you:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

How to avoid Swift 6 concurrency warning from UIAccessibility.post()
 
 
Q