Reputation: 2325
I'm I'm playing with the new swiftData I'm try to understand how the relations work my happy to have to model class:
Each Flight on my APP contained many crews, I wrote the relation like in the following code but keep getting the error " Fatal error: Inverse Relationship does not exist"
How should we write this relation:
@Model
class Flight {
@Attribute(.unique) var flightID: UUID
var typeOfFlight: String
var flightDateUTC : Date
var flightNumber: String?
@Relationship(.cascade) var flightData: FlightData
@Relationship(.cascade) var flightTime : FlightTime
@Relationship(.noAction) var aircraft : Aircraft?
@Relationship(inverse: \CrewModel.name)
var crews : [CrewModel]? //<-------------------------------
init(flightID: UUID, typeOfFlight: String, flightDateUTC: Date, flightNumber: String? = nil, flightData: FlightData, flightTime: FlightTime, aircraft: Aircraft? = nil, crews: [CrewModel]? = nil) {
self.flightID = flightID
self.typeOfFlight = typeOfFlight
self.flightDateUTC = flightDateUTC
self.flightNumber = flightNumber
self.flightData = flightData
self.flightTime = flightTime
self.aircraft = aircraft
self.crews = crews
}
}
@Model
class CrewModel{
@Attribute(.unique) var id: UUID = UUID()
@Relationship(.noAction, inverse: \Flight.flightID)
var name : String?
var crewID: String?
var company: String?
var isMe: Int?
var email: String?
var phone: String?
var score: Int?
var isPIC: Int?
var isSIC: Int?
var dataImage: Data?
var comment: String?
init(id: UUID, name: String? = nil, crewID: String? = nil, company: String? = nil, isMe: Int? = nil, email: String? = nil, phone: String? = nil, score: Int? = nil, isPIC: Int? = nil, isSIC: Int? = nil, dataImage: Data? = nil, comment: String? = nil) {
self.id = id
self.name = name
self.crewID = crewID
self.company = company
self.isMe = isMe
self.email = email
self.phone = phone
self.score = score
self.isPIC = isPIC
self.isSIC = isSIC
self.dataImage = dataImage
self.comment = comment
}
}
Upvotes: 4
Views: 3234
Reputation: 66
Adding on to Joakim’s answer, you shouldn’t be dealing with an optional array. It makes sense if you think of the scenario where no crew is assigned to a specific Flight
, the array is going to be empty, not missing.
You should change it to the following for this reason:
@Relationship(inverse: \CrewModel.flight) var crews = [CrewModel]()
Also I’m creating an empty array at the model’s initialization, because you’re more likely to run into issues if you’re trying to insert a new Flight
that already has references to other CrewModel
s, over simply creating the Flight
, inserting it into SwiftData, and then appending CrewModel
s to it.
Upvotes: 2
Reputation: 51973
When using the inverse
parameter you only need to define the relationship in one of the model types. The value for inverse
must point to a property of the type of the model.
in Flight
@Relationship(inverse: \CrewModel.flight) var crews : [CrewModel]?
and in CrewModel
var flight: Flight?
Upvotes: 9