Home > database >  How to Initialize Codable ObservedObject
How to Initialize Codable ObservedObject

Time:01-21

In SwiftUI, I'm trying to create a class that conforms Codable (so I can save it in @AppStorage), and has @Published properties so it can be passed as an EnvironmentObject.

This tutorial gave me the following example:

class User: ObservableObject, Codable {
    
    enum CodingKeys: CodingKey {
        case name
    }
    
    @Published var name = "Bob Smith"
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        name = try container.decode(String.self, forKey: .name)
    }
    
    func encode(to encoder: Encoder) throws {
        ...
    }
}

I'm wondering how I would go about passing a String into the class initializer. (i.e. var user = User("Bob Smith")

Unless I'm mistaken, required means that all instances & subclasses must use that initializer. Given that name is already being assigned in the existing initializer, how would I go about passing a custom name into the initializer of this class?

CodePudding user response:

Yes required means that all subclasses must implement the init and in this case it's a requirement because of the conformance to Codable.

But this doesn't mean you can't add other initialisers so that you can create instances of your class from other type of data than JSON

So simply add wathever init you need

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

let user = User(name: "Joe")

And for a sub class you must add an init(from:) and you might add another custom init if you want to, here is an example

class SuperUser: User {
    var likesBananas: Bool

    enum CodingKeys: CodingKey {
        case likesBananas
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        likesBananas = try container.decode(Bool.self, forKey: .likesBananas)

        try super.init(from: decoder)
    }

    init(name: String, likesBananas: Bool) {
        self.likesBananas = likesBananas
        super.init(name: name)
    }

    override func encode(to encoder: Encoder) throws {...}
}
  • Related