andre de waard
andre de waard

Reputation: 164

Swift class inheritance initializer error

What do I need to add to extend the UserModel with AuthenticatedUserModel without getting this error? // 'required' initializer 'init(from:)' must be provided by subclass of 'UserModel'

I know I can also just add the accessToken to the UserModel as optional but I want to understand what's going on so I can understand swift a bit better?

class UserModel: Codable, Identifiable, ObservableObject {
    let id: Int
    let firstName: String?
    let lastName: String?
    let username: String?
    let bio: String?
    let theme: String?
    let imageSrc: String?
    let interests: [String]?
    let followerCount: Int?
    let following: Bool?
    let followingCount: Int?
    let hasCompletedRegistration: Bool?
    let isPrivate: Bool?
    let readerMode: Bool?
    let isActive: Bool?
    let isVerified: Bool?
    let isSuspended: Bool?
    let isAdmin: Bool?
    let isFollowing: Bool?
    let createdAt: String?
    let updatedAt: String?
    
    init(id: Int, firstName: String, lastName: String, bio: String) {
        self.id = id
        self.firstName = firstName
        self.lastName = lastName
        
        self.username = ""
        self.bio = ""
        self.theme = ""
        self.imageSrc = ""
        self.interests = [""]
        self.followerCount = 0
        self.following = false
        self.followingCount = 0
        self.hasCompletedRegistration = true
        self.isPrivate = false
        self.readerMode = true
        self.isActive = true
        self.isVerified = false
        self.isSuspended = false
        self.isAdmin = false
        self.isFollowing = false
        self.createdAt = ""
        self.updatedAt = ""
    }
    
    var name: String {
        return "\(firstName ?? "") \(lastName ?? "")"
    }
}

class AuthenticatedUserModel: UserModel {
    let accessToken: String?
    
    override init(id: Int, firstName: String, lastName: String, bio: String) {
        self.accessToken = nil
        super.init(id: id, firstName: firstName, lastName: lastName, bio: bio)
    }
}

Upvotes: 0

Views: 71

Answers (1)

matzino
matzino

Reputation: 3564

The Decodable protocol requires the implementation of the method init(from:). Cause of adding a new property the automatically created init(from:) method of the parent class is not inherited. This happens cause the inherited method can not initialize the new property from the child class.

Therefore the solution is to add the required method. For example like this (untested code)

required init(from decoder: Decoder) throws {
    accessToken = try decoder.singleValueContainer().decode(String.self)
    try super.init(from: decoder)
}

Upvotes: 1

Related Questions