I have multiple classes that are contained within one another.
Initializing class A(no other classes as properties) has no issues, but the moment that it tries to initialize class B, which takes class A as a property, an EXC_BAD_ACCESS error is thrown while attempting to set the first property value.
Class A:
import Foundation
import SwiftData
@Model
public class Service: Identifiable, Equatable, Codable {
@Attribute(.unique)
public var id: UUID
public var title: String
public var price: Int
public var stripePriceId: String
public var servicePhoto: String
public var serviceLength: Int
public var category: [String]
init(id: UUID, title: String, price: Int, stripePriceId: String, servicePhoto: String, serviceLength: Int, category: Array<String>) {
self.id = id
self.title = title
self.price = price
self.stripePriceId = stripePriceId
self.servicePhoto = servicePhoto
self.serviceLength = serviceLength
self.category = category
}
}
Class B:
import Foundation
import SwiftData
import SwiftUI
@Model
public class ServiceOrder: Identifiable, Codable, Equatable {
public var id: UUID
@Relationship(.noAction)
public var service: Service
public var quantity: Int = 1
public var subtotal: Int { return service.price * quantity }
public init(id: UUID = UUID(), service: Service, quantity: Int) {
self.id = id
self.service = service
self.quantity = quantity
}
public func getValue<T>(for key: KeyPath<ServiceOrder, T>) -> T {
return self[keyPath: key]
}
// This is where the error is being thrown. The custom setValue and getValue methods were added to every class to mitigate an 'Ambiguous use of __Value()' error, but that's for another thread
public func setValue<T>(for key: ReferenceWritableKeyPath<ServiceOrder, T>, to newValue: T) {
self[keyPath: key] = newValue
}
// This was added to see if following the Builder pattern might mitigate the issue by ensuring that all properties were initialized before being passed in, it did not change anything
class ServiceOrderBuilder {
private var id: UUID?
private var service: Service?
private var quantity: Int?
init() {
}
init(id: UUID = UUID(), service: Service, quantity: Int = 1) {
self.id = id
self.service = service
self.quantity = quantity
}
func setId(id: UUID = UUID()) -> ServiceOrderBuilder {
self.id = id
return self
}
func setService(service: Service) -> ServiceOrderBuilder {
self.service = service
return self
}
func setQuantity(quantity: Int = 1) -> ServiceOrderBuilder {
self.quantity = quantity
return self
}
func build() -> ServiceOrder? {
guard let id = id, let service = service, let quantity = quantity else {
return nil
}
return ServiceOrder(id: id, service: service, quantity: quantity)
}
}
Here's where I'm doing the initialization of everything. I'm trying to just create sample data.
import SwiftData
import Foundation
@MainActor
public let previewContainer: ModelContainer = {
do {
var container = try ModelContainer(
for: [Event.self, Braider.self, Queue.self, QueueSlot.self, Cart.self, ServiceOrder.self],
ModelConfiguration(inMemory: true)
)
var context = container.mainContext
var serviceSampleData: [Service] = [
Service(
id: UUID(),
title: "Event Braid",
price: 20, stripePriceId: "",
servicePhoto: "",
serviceLength: 15,
category: []),
...,
]
serviceSampleData.forEach { service in
context.insert(service)
}
// This is where the error is thrown, no issue initializing the above Services
var serviceOrder1: ServiceOrder = ServiceOrder(
service: serviceSampleData[0],
quantity: 1)
context.insert(serviceOrder1)
// ...continue building higher classes/Models that utilize the lower ones
return container
} catch {
print("Failed to create container")
do {
return try ModelContainer(
for: [Event.self],
ModelConfiguration(inMemory: true)
)
} catch {
fatalError()
}}
}()
I assumed that this was a SwiftData issue, as I mentioned in response to this post but looking back this issue has been happening for 7+ years, so now I'm assuming I'm doing something incorrect.