SwiftData Model Inheriting from Codable Class

136 Views Asked by At

I have a backend written in swift (hosted on GCP Cloud Run, aka linux so no access to Apple-specific frameworks).

I have a regular codable class:

open class MyClass: Codable, Identifiable {
    var id: String
    var name: String

    init(id: String, name: String) {
        self.id = id
        self.name = name
    }
}

That I share across the frontend and backend (via a swift package) thus allowing me to send that data from the backend to frontend easily by encoding the object on the backend and decoding the object on the frontend.

I now want to manage data on the frontend using SwiftData, but I can't seem to set this up properly.

How can I do this properly? Or if this isn't possible (I've heard inheritance and codable can cause issues with SwiftData) is there another approach I can take here?

My Initial Attempt: My initial attempt was to just create a super class with the @Model macro:

@Model
class MyFrontendClass: MyClass { }

This then gives me the error:

@Model requires an initializer be provided for 'MyFrontendClass'

When I created a basic initializer that calls the other classes's initializer:

@Model
class MyFrontendClass: MyClass {
    override init(id: String, name: String) {
        super.init(id: id, name: name)
    }
}

I then get the error (inside the @Model macro's generated code):

'required' initializer 'init(from:)' must be provided by subclass of 'MyClass'

I've then tried adding that initializer:

@Model
class MyFrontendClass: MyClass {
    override init(id: String, name: String) {
        super.init(id: id, name: name)
    }
    required init(from decoder: Decoder) throws {
        try super.init(from: decoder)
    }
}

At this point I get the error:

1. 'self' used in property access 'persistentBackingData' before 'super.init' call
2. 'super.init' isn't called on all paths before returning from initializer

in the @Model macro generated code:

required init(backingData: any SwiftData.BackingData<MyFrontendClass>) {

  self.persistentBackingData = backingData
}
0

There are 0 best solutions below