I have a MovieData class that conforms to SwiftData model as @Model such as:
@Model
class MovieData: Codable{
var ....
}
We also have a web service struct that returns a MovieData array from an API:
struct WebService {
func getMoviesArr() async -> [MovieData]{
do {
let data = try await getDataFromURL(callType: .movies)
return try JSONDecoder().decode([MovieData].self, from: data)
} catch {
print("Failed to fetch movies arr: \(error)")
return []
}
}
}
The issue I am facing is, while importing the movies list to save them using SwiftData on a background actor created by @ModelActor the error is obviously Non-sendable type '[MovieData]' returned by implicitly asynchronous call to nonisolated function cannot cross actor boundary
As SwiftData models cannot conform to the Sendable protocol I cannot use a seperate class/struct to better organize the code and make more modular.
Calling the struct and the method from my actor:
@ModelActor
actor UpdateActor: Sendable{
func downloadAndWriteMovies(context: ModelContext) async -> [MovieData]{
let webService = WebService()
let moviesArr = await webService.getMoviesArr() \\ <- Creating the error
context.insert(moviesArr)
return moviesArr
}
}
Any ideas how to go around it instead of putting all the code in our @ModelActor or create extensions for that actor?
@Modelclass. Write someSendablestructs that contains all the information you need to create your@Modelclass, and decode to those structs instead. These are not "redundant" - this is how you make your code thread safe.