I've been stuck on this for the past week and I'm asking here out of desperation. I have a project using Swift 5, and I recently enabled “Strict Concurrency Checking” to “Complete” so I can slowly migrate my project to Swift 6 without everything breaking. I have a view model that interfaces with SwiftData and has worked with no problems up until now.
I'm getting a warning for the line that, at the sortBy: [SortDescriptor(\.date)] line, says:
Type 'KeyPath<CachedMessage, Date>' does not conform to the 'Sendable' protocol; this is an error in the Swift 6 language mode.
Here is my code:
import SwiftUI
import SwiftData
@MainActor final class MyViewModel: ObservableObject {
private(set) var modelContext: ModelContext?
private var tempMessagesCache: [Message] = []
@Published var messages: [Message] = []
func setModelContext(_ modelContext: ModelContext) {
self.modelContext = modelContext
self.modelContext!.autosaveEnabled = false
}
func fetchCachedMessages(for chatGroupId: String) {
do {
let descriptor = FetchDescriptor<CachedMessage>(
predicate: #Predicate { $0.chatGroupId == chatGroupId },
sortBy: [SortDescriptor(\.date)]
)
if let messages = try modelContext?.fetch(descriptor) {
tempMessagesCache = messages.map({
Message(cachedMessage: $0)
})
}
} catch {
// Handle error
}
}
}
struct Message {
let id: String
let chatGroupId: String
let date: Date
// more metadata here
// other initializers here
init(cachedMessage: CachedMessage) {
self.id = cachedMessage.id
self.chatGroupId = cachedMessage.chatGroupId
self.date = cachedMessage.date
// more metadata here
}
}
// I already tried conforming CachedMessage to the Sendable protocol but same error.
@Model final class CachedMessage {
@Attribute(.unique) private(set) var id: String
private(set) var chatGroupId: String
private(set) var date: Date
// more metadata here
// other initializers here
init(message: Message) {
self.id = message.id
self.chatGroupId = message.chatGroupId
self.date = message.date
// more metadata here
}
}
I'm getting a warning for the line that says sortBy: [SortDescriptor(\.date)]:
"Type 'KeyPath<CachedMessage, Date>' does not conform to the 'Sendable' protocol; this is an error in the Swift 6 language mode."
Is there a way for me to fetch data from the SwiftData ModelContext in this way in Swift 6? Here is the definition of KeyPath when I jump to definition in Xcode:
/// A key path from a specific root type to a specific resulting value type.
///
/// The most common way to make an instance of this type
/// is by using a key-path expression like `\SomeClass.someProperty`.
/// For more information,
/// see [Key-Path Expressions][keypath] in *[The Swift Programming Language][tspl]*.
///
/// [keypath]: https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#ID563
/// [tspl]: https://docs.swift.org/swift-book/
public class KeyPath<Root, Value> : PartialKeyPath<Root> {
}
I've also tried reading through the Apple documentation in the link provided in their definition: https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#ID563
I haven't found anything else that can help me which is why I'm coming here for any potential help. ChatGPT and Claude solutions don't work (mostly just suggesting marking the function as @MainActor, or extracting the SortDescriptor(\.date) object.
Any help would be really appreciated. Thank you.
)in....sortBy: [SortDescriptor(\.date)] )KeyPathis not conform toSendableso a quick fix is mark it as@unchecked Sendable-enable-upcoming-feature InferSendableFromCapturesas discussed in FetchDescriptor including SortDescriptor returns warning in Xcode16 or 6.0 Strict Concurrency Warning when KeyPath marked as Sendable.KeyPathand add@retroactiveto silence this warning for now.