Here is my current code:
@Model
final public class ServerModel {
@Attribute(.unique) var serverUrl: URL
init(serverUrl: URL) {
self.serverUrl = serverUrl
}
}
@ModelActor
public actor MyDatabaseService {
public static var shared = MyDatabaseService()
public init() {
self.modelContainer = try! ModelContainer(for: ServerModel.self)
let context = ModelContext(modelContainer)
self.modelExecutor = DefaultSerialModelExecutor(modelContext: context)
}
public func listServers() throws -> [ServerModel] {
let descriptor = FetchDescriptor<ServerModel>()
return try modelContext.fetch(descriptor)
}
}
When try to call try await MyDatabaseService.shared.listServers()
There are two problems:
ServerModel
is notSendable
- "Reference to static property 'shared' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6"
For the first one, I can solve it by doing:
public struct Server {
let serverUrl: URL;
}
@Model
final public class ServerModel {
@Attribute(.unique) var serverUrl: URL
init(serverUrl: URL) {
self.serverUrl = serverUrl
}
func getSendable() -> Server {
return Server(serverUrl: self.serverUrl)
}
}
@ModelActor
public actor MyDatabaseService {
(...)
public func listServers() throws -> [Server] {
let descriptor = FetchDescriptor<ServerModel>()
return try modelContext.fetch(descriptor).map { $0.getSendable() }
}
}
I am wondering if there is a smarter solution to this first issue. SwiftData already require to define the model with basic/codable types, so if there was a magic way to get a sendable from the model. I try to make my model 'Codable' but 'Codable' is not compatible with 'Sendable'.
For my second issue, the singleton issue. I do not really know how to fix it.