'self' used before all stored properties are initialized and I have not idea why

No idea why this error occurred, and I suspect that it's me putting initialization in the wrong place.


struct TodosDocument: FileDocument {
    var todo: Context
    @AppStorage("defaultText")
    var defaultText: String = defaultContent
    var content: String
    var erroreousFileContent: Bool = false
    init(content: String = defaultContent, defaultText: String = defaultContent) {
        self.defaultText = defaultText
        self.content = content
        do {
            self.todo = try JSONDecoder().decode(Context.self, from: content.data(using: .utf8)!)
        } catch {
            print("ERROR \(error)")
            fatalError()
        }
    }

    
    static var readableContentTypes: [UTType] { [.TodoType] }

    init(configuration: ReadConfiguration) throws {
        guard let data = configuration.file.regularFileContents,
              let string = String(data: data, encoding: .utf8)
        else {
            throw CocoaError(.fileReadCorruptFile)
        }
        self.content = string
        do {
            self.todo = try JSONDecoder().decode(Context.self, from: data)
        } catch {
            self.todo = try JSONDecoder().decode(Context.self, from: defaultText.data(using: .utf8)!) // <- here
        }
    }
    
    func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
        let data = content.data(using: .utf8)!
        let i = JSONEncoder()
        i.outputFormatting = .prettyPrinted
        let content = Context(title: todo.title, items: todo.items)
        do {
            let dat = try i.encode(content)
            return .init(regularFileWithContents: dat)
        } catch {
            fatalError("Cannot write content \"\(data)\" with \(configuration): \(error)")
        }
    }
}

Answered by Claude31 in 715019022

You should initialise todo first.

For instance, in its declaration (You do not show what Context is, so I guess), something like:

    var todo: Context = Context()  // <<-- 

Or you could do it in init

    init(configuration: ReadConfiguration) throws {
        guard let data = configuration.file.regularFileContents,
              let string = String(data: data, encoding: .utf8)
        else {
            throw CocoaError(.fileReadCorruptFile)
        }
        self.content = string
        self.todo = Context()  // <<--

OK

Maybe like this

Accepted Answer

You should initialise todo first.

For instance, in its declaration (You do not show what Context is, so I guess), something like:

    var todo: Context = Context()  // <<-- 

Or you could do it in init

    init(configuration: ReadConfiguration) throws {
        guard let data = configuration.file.regularFileContents,
              let string = String(data: data, encoding: .utf8)
        else {
            throw CocoaError(.fileReadCorruptFile)
        }
        self.content = string
        self.todo = Context()  // <<--
'self' used before all stored properties are initialized and I have not idea why
 
 
Q