Search code examples
swiftinitializationswift5

Swift 5: 'self' used before 'self.init' call


I'm trying to use a required convenience failable initializer. Here's the code I'm working with:

public init(authState: OIDAuthState, config: [String: String], accessibility: CFString = kSecAttrAccessibleWhenUnlockedThisDeviceOnly) throws {
        self.authState = authState
        self.config = config
        self.accessibility = accessibility

        super.init()

        KeycloakAuth.configuration = config
    }

public required convenience init?(coder aDecoder: NSCoder) {
        try? self.init(authState:     aDecoder.decodeObject(forKey: "authState")     as! OIDAuthState,
                       config:        aDecoder.decodeObject(forKey: "config")        as! [String: String],
                       accessibility: aDecoder.decodeObject(forKey: "accessibility") as! CFString)
    }

I get the error 'self' used before 'self.init' call on the public required... line, and the same error again on the try? self.init(... line.

I've looked at a few other related questions on Stack Overflow. Namely these:

  1. iOS Swift convenience initializer self used before self.init called
  2. 'self' used before self.init call error while using NSCoding on a custom class

So I arranged my convenience init accordingly to try and return nil if there were any problems:

public required convenience init?(coder aDecoder: NSCoder) {
        guard
            let authState     = aDecoder.decodeObject(forKey: "authState")     as? OIDAuthState,
            let config        = aDecoder.decodeObject(forKey: "config")        as? [String: String]
        else {
            print("KeycloakTokenManager: There was an error intializing authState or config")
            return nil
        }

        let accessibility = aDecoder.decodeObject(forKey: "accessibility") as! CFString

        try? self.init(authState: authState, config: config, accessibility: accessibility)
    }

But I'm getting same the errors on the same code (initializer, and call to self.init). Interestingly, my project built fine on Swift 4, but I haven't heard anything about this being a bug is Swift 5. How can I get rid of this error?


Solution

  • A solution is not to call the designated initializer

    public required init?(coder aDecoder: NSCoder) {
        guard
            let authState     = aDecoder.decodeObject(forKey: "authState")     as? OIDAuthState,
            let config        = aDecoder.decodeObject(forKey: "config")        as? [String: String]
        else {
            print("KeycloakTokenManager: There was an error intializing authState or config")
            return nil
        }
    
        self.authState = authState
        self.config = config 
        self.accessibility =  aDecoder.decodeObject(forKey: "accessibility") as! CFString
    
        super.init()
    
        KeycloakAuth.configuration = config
    }