I’m trying to resolve a compilation error: Task or actor isolated value cannot be sent
when using Xcode 16.0 beta 3 with Swift 6 and Complete
Concurrency enabled. My code:
import SwiftUI
@preconcurrency import Contacts
import ContactsUI
struct SimpleContactPicker: View {
let allowedContactType: CNContactType? = CNContactType.person
@Binding var selectedContacts: [CNContact]?
var body: some View {
SimpleContactPickerProxy(allowedContactType: self.allowedContactType, selectedContacts: $selectedContacts)
.ignoresSafeArea()
}
}
extension CNContactType {
var predicateForEnablingContact: NSPredicate {
NSPredicate(format: "contactType=(self.rawValue)")
}
}
struct SimpleContactPickerProxy: UIViewControllerRepresentable, @unchecked Sendable {
typealias UIViewControllerType = CNContactPickerViewController
let allowedContactType: CNContactType?
@Binding var selectedContacts: [CNContact]?
final class Coordinator: NSObject, CNContactPickerDelegate, @unchecked Sendable {
var parent: SimpleContactPickerProxy
init(_ parent: SimpleContactPickerProxy) {
self.parent = parent
}
func contactPickerDidCancel(_ picker: CNContactPickerViewController) {
}
func contactPicker(_ picker: CNContactPickerViewController, didSelect contacts: [CNContact]) {
Task { @MainActor in
self.parent.selectedContacts = contacts // <<-- ERROR: Task or actor isolated value cannot be sent
}
}
}
func makeUIViewController(context: Context) -> CNContactPickerViewController {
let contactPickerViewController = CNContactPickerViewController()
contactPickerViewController.delegate = context.coordinator
if let allowedContactType {
contactPickerViewController.predicateForEnablingContact = allowedContactType.predicateForEnablingContact
}
return contactPickerViewController
}
func updateUIViewController(_ uiViewController: CNContactPickerViewController, context: Context) {
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
}
While I generally understand that the [CNContact]
array cannot be sent from the non-isolated context to the MainActor
context because CNContact
is non-Sendable, it’s unclear how to work around this problem. (This issue did not appear in earlier Xcode 16 betas).
I guess it’s possible to create my own CNContact
facsimile struct with copied data, but this seems like an annoying amount of overhead. I also tried MainActor.assumeIsolated
and other strategies discussed in this WWDC 2024 Swift Concurrency video https://developer.apple.com/wwdc24/10169, but none of these approaches appeared to work.
Any help is appreciated.