Search code examples
swiftnskeyedarchivernssecurecoding

Why is this subclass failing to be archived by NSKeyedArchived?


I have this class that have to be the subclass of OIDAuthState (this class is an NSObject and conforms to NSSecureCoding),

The code to encode the class OIDAuthState was working fine before

self.data = try NSKeyedArchiver.archivedData(withRootObject: authState, requiringSecureCoding: true)

Once I created this subclass that includes adds a simple Boolean to the class isExpiredTokenEnforced, I now get the error when using NSKeyedArchiver,

The error says:

NSDebugDescription=Caught exception during archival: *** -decodeBoolForKey: only defined for abstract class. Define -[NSKeyedArchiver decodeBoolForKey:]!

Here is the subclass I am trying to archive and down below the override method to encode and decode this class, I am simply encoding and decoding this 1 extra property and then passing down the coder to the parent class,

class AuthenticationStateManager: OIDAuthState, AuthenticationState {
    var isExpiredTokenEnforced = false

    var lastTokenResponseInterface: TokenResponse? {
        if isExpiredTokenEnforced {
            return EnforcedExpiredTokenResponse(idToken: super.lastTokenResponse?.idToken,
                                                accessToken: super.lastTokenResponse?.accessToken)
        } else {
            return super.lastTokenResponse
        }
    }

    override static var supportsSecureCoding: Bool { true }

    required override init(authorizationResponse: OIDAuthorizationResponse?, tokenResponse: OIDTokenResponse?, registrationResponse: OIDRegistrationResponse?) {
        super.init(authorizationResponse: authorizationResponse, tokenResponse: tokenResponse, registrationResponse: registrationResponse)
    }

    required init?(coder: NSCoder) {
        coder.encode(isExpiredTokenEnforced, forKey: "isExpiredTokenEnforced")
        super.init(coder: coder)
    }

    override func encode(with coder: NSCoder) {
        self.isExpiredTokenEnforced = coder.decodeBool(forKey: "isExpiredTokenEnforced")
        super.encode(with: coder)
    }
}

I can't figure out why this is failing I couldn't find relevant information to fix this,

does anyone have a clue what could be wrong here?

Thank you in advance for your time.


Solution

  • You are mixing up your encoder and decoder functions. Your func encode() is trying to call decodeBool. It should be calling encode().

    Similarly your init?(coder:) function should be calling decode (or rather decodeBool(forKey:).)