I am trying to make a sample app which uses SwiftData to keep track of sports goals. I have a struct: Team
which has values id
(UUID), name
(string), score
(int), and editing
(bool). I have a SwiftData model class which contains the values id
(UUID), teams
([Team]), pro
(Boolean). Normally, the class works fine without having the teams
array in the CounterModel
class, but as soon as I add var teams: [Team]
to the class, I get the following errors:
Type 'CounterModel' does not conform to protocol 'PersistentModel'
No exact matches in call to instance method 'getValue'
No exact matches in call to instance method 'setValue'
The class conforms to Identifiable, Hashable. The struct also conforms to these protocols. Conforming both to Codable does not make the error go away.
Here is my code if needed:
import Foundation
import SwiftData
@Model
class CounterModel: Identifiable, Hashable {
@Attribute(.unique) var id = UUID()
var teams: [Team]
var pro: Bool
init(teams: [Team], pro: Bool) {
self.teams = teams
self.pro = pro
}
func toTeamArr() -> [Team] {
return teams
}
}
struct Team: Identifiable, Hashable {
var id: UUID = UUID()
var name: String
var score: Int
var editing: Bool = false
}
edit: I have also tried putting the Team struct inside of the class. Same error.
edit2: following a suggestion by a reply, here is the updated code:
import Foundation
import SwiftData
@Model
class CounterModel: Identifiable, Hashable {
@Attribute(.unique) var id = UUID()
@Relationship(.cascade) var teams: [Team]
var pro: Bool
init(teams: [Team], pro: Bool) {
self.teams = teams
self.pro = pro
}
func toTeamArr() -> [Team] {
return teams
}
}
@Model
class Team: Identifiable, Hashable {
@Attribute(.unique) var id: UUID = UUID()
var name: String
var score: Int
@Transient var editing: Bool = false
init(name: String, score: Int, editing: Bool = false) {
self.name = name
self.score = score
self.editing = editing
}
}
Now, there are only 2 errors produced:
- Type ‘CounterModel’ does not conform to protocol ‘PersistentModel’
- Type ‘Team’ does not conform to protocol ‘PersistentModel’
Edit 3: Upon extracting the models into a separate Xcode project, it builds fine. When I bring the rest of my code into the project, it stops working. Will investigate further.
Okay. It seems to be an issue with passing the data from the @Query modifier into different views. Upon removing the parameters for the CounterModel
data model from the views, the app compiled fine. I’m assuming, and hoping that this is a bug. For now, I’ll just query the data separately in the views. Thank you all for your help! I have submitted feedback on the issue, just in case: FB12338703
2
Answers
Okay. It seems to be an issue with passing the data from the @Query modifier into different views. Upon removing the parameters for the CounterModel data model from the views, the app compiled fine. I'm assuming, and hoping that this is a bug. For now, I'll just query the data separately in the views. Thank you all for your help!
There are two changes you need to make to your model classes.
The first, is to change
Team
to a class and make it an@Model
The second change is to tell SwiftData that
teams
is a reference to another SwiftData entity using the@Relationship
decorator.The
.cascade
argument to@Relationship
tells SwiftData to delete all of the referencedTeam
objects if theCounterModel
object is deleted.