How to wrangle Sendable ReferenceFileDocument and SwiftUI

I recently circled back to a SwiftUI Document-based app to check on warnings, etc. with Xcode 16 and Swift 6 now released. I just found a suite a new errors that indicate that ReferenceFileDocument is now expected to be Sendable, which seems very off for it fundamentally being a reference type.

I followed the general pattern from earlier sample code: Building Great Apps with SwiftUI, which goes from an Observable object to adding conformance to ReferenceFileDocument in an extension. But then the various stored properties on the class cause all manner of complaint - given that they're not, in fact, sendable.

What is an expected pattern that leverages a final class for the ReferenceDocument, but maintains that Sendability? Or is there a way to "opt out" of Sendability for this protocol?

I'm at a bit of a loss on the expectation that ReferenceFileDocument is sendable at all, but since it's marked as such, I'm guessing there's some path - I'm just not (yet) clear on how to accomodate that.

Answered by DTS Engineer in 807076022

I think the ReferenceFileDocument documentation is helpful here:

Ensure that types that conform to this protocol are Sendable. In particular, SwiftUI calls the protocol’s methods from different isolation domains.

IOW, ReferenceFileDocument can't be not Sendable, because it's potentially accessed from different isolation domains (actor contexts), and that wouldn't be safe without the Sendable guarantee.

If you look at the code sample on the same page, you can see that it uses a Swift-concurrency-compatible lock to show one simple way to provide sendability.

In your case, your goal is not to make the stored properties Sendable, but to make the class itself Sendable.

Depending on what your document class does, you may be able to do something similar to the lock, but the solution will depend on your app's performance and data handling requirements.

Accepted Answer

I think the ReferenceFileDocument documentation is helpful here:

Ensure that types that conform to this protocol are Sendable. In particular, SwiftUI calls the protocol’s methods from different isolation domains.

IOW, ReferenceFileDocument can't be not Sendable, because it's potentially accessed from different isolation domains (actor contexts), and that wouldn't be safe without the Sendable guarantee.

If you look at the code sample on the same page, you can see that it uses a Swift-concurrency-compatible lock to show one simple way to provide sendability.

In your case, your goal is not to make the stored properties Sendable, but to make the class itself Sendable.

Depending on what your document class does, you may be able to do something similar to the lock, but the solution will depend on your app's performance and data handling requirements.

How to wrangle Sendable ReferenceFileDocument and SwiftUI
 
 
Q