ikunhub
ikunhub

Reputation: 283

Swiftdata Fatal error: Composite Coder only supports Keyed Container

When I try to instantiate a ModelContainer object, I get an error. The error is like this:

Thread 1: Fatal error: Composite Coder only supports Keyed Container.

SingleFolder is a custom model.

This is my code:

class DatabaseService {
    static var shared = DatabaseService()
    
    var container: ModelContainer?
    var context: ModelContext?
    
    init() {
        do {
            container = try ModelContainer(for: [SingleFolder.self])
            if let container {
                context = ModelContext(container)
            }
        } catch {
            print(error)
        }
    }
}

enter image description here

I'm expecting to generate a ModelContainer singleton so I can access it anytime. What's wrong with this?

Xcode version 15.0 beta4 Simulator version: iOS 17.0

This is my model:

@Model class SingleFolder {
    let creationTime: Date
    var editTime: Date
    var folderName: String
    
    var frame: CGRect = CGRect.zero

    init(creationTime: Date, editTime: Date, folderName: String) {
        self.creationTime = creationTime
        self.editTime = editTime
        self.folderName = folderName
    }
}

Upvotes: 4

Views: 1201

Answers (2)

John
John

Reputation: 1816

I'm seeing the same crash and fatal error, but with a ClosedRange instead of CGRect. This is with XCode 15.0.1 and iOS 17.0.

Setting the initial value in init solves it, but not sure why.

Edit: That just let the app launch. It still crashed with the same fatal error when trying to add it to the context. I realized it is probably the data type. In my case, I just changed my class to store the lower and upper bounds of a range and that resolved this.

Upvotes: 2

ikunhub
ikunhub

Reputation: 283

The problem seems to be that the initial value of a CGRect object cannot be provided in the model.

this works:

@Model class SingleFolder {
    let creationTime: Date
    var editTime: Date
    var folderName: String
    
    var frame: CGRect

    init(creationTime: Date, editTime: Date, folderName: String, frame: CGRect) {
        self.creationTime = creationTime
        self.editTime = editTime
        self.folderName = folderName
        self.frame = frame
    }
}

but this doesn't work:

@Model class SingleFolder {
    let creationTime: Date
    var editTime: Date
    var folderName: String
    
    var frame: CGRect = CGRect.zero

    init(creationTime: Date, editTime: Date, folderName: String) {
        self.creationTime = creationTime
        self.editTime = editTime
        self.folderName = folderName
    }
}

But when I set initial values for other types of properties, it works again:

@Model class SingleFolder {
    let creationTime: Date
    var editTime: Date
    var folderName: String = "this is a folder"
    
    var frame: CGRect

    init(creationTime: Date, editTime: Date, frame: CGRect) {
        self.creationTime = creationTime
        self.editTime = editTime
        self.frame = frame
    }
}

Upvotes: 3

Related Questions