Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSSecureCoding how to override the required supportsSecureCoding in a subclass

I'm trying to resolve this runtime error on an iOS project using swift 5

The class must implement +supportsSecureCoding and return YES to verify that its implementation of -initWithCoder: is secure coding compliant." UserInfo={NSDebugDescription=Class 'Divinstructor.ResultDE' has a superclass that supports secure coding, but 'Divinstructor.ResultDE' overrides -initWithCoder: and does not override +supportsSecureCoding. The class must implement +supportsSecureCoding and return YES to verify that its implementation of -initWithCoder: is secure coding compliant.}

However I have not found a way to overcome this error as try to follow the error instruction result in a compilation error that I still fail to solve

I'm updating my application to NSSecureCoding. NSKeyedUnarchiver.unarchiveObject(with:) is deprecated starting iOS12 and have to be replaced by NSKeyedUnarchiver.unarchivedObject(ofClass: ,from: ) which indeed turn in having to move away from NSCoding for NSSecureCoding.

It works for my main class (Result) that I modify to conform to NSSecureCoding. One of the required stuff is to add in the class that conforms to NSSecureCoding

static var supportsSecureCoding: Bool = true

However I'm facing an issue at runtime (see above) for a class (ResultDE) that is inherit from my class (Result).

The error message says that "ResultDE' has a superclass that supports secure coding, but 'Divinstructor.ResultDE' overrides -initWithCoder: and does not override +supportsSecureCoding."

However I have tried many options to override supportsSecureCoding but without any success.

override public static var supportsSecureCoding: Bool= true

The obvious one above also produce the compilation error "Cannot override with a stored property 'supportsSecureCoding'" All my attempts result in a compilation error. "Cannot override with a stored property 'supportsSecureCoding'"

So is anybody as an idea of how to override supportsSecureCoding in a subclass ?

I tried to remove static for the supportsSecureCoding in the man class (making it non conform to protocol) and I still have the "Cannot override with a stored property 'supportsSecureCoding'" compilation error.

here is a short code that reproduce the compilation error


import Foundation

class Result : NSObject, NSSecureCoding {


    static var supportsSecureCoding: Bool = true

    var name: String = "-"

    override init() {
        super.init()
    }

    required init(coder decoder: NSCoder) {
        super.init()
        name = decoder.decodeObject(forKey: "name") as! String
    }
    func encode(with coder: NSCoder) {
        coder.encode(name, forKey: "name")
    }



    class ResultDE: Result {
        override static var supportsSecureCoding: Bool = true

        required init(coder decoder: NSCoder) {
            super.init()
            name = decoder.decodeObject(forKey: "name") as! String
        }
        override func encode(with coder: NSCoder) {
            coder.encode(name, forKey: "name")
        }
    }

}
like image 937
Stephane Gasparini Avatar asked Aug 31 '25 01:08

Stephane Gasparini


1 Answers

Thanks to Itai Ferber here is the way to do it.

static var supportsSecureCoding: Bool = true

need to be replaced by

class var supportsSecureCoding: Bool {true}

class then can be overridden in sub-classes.

Here code example with the fixes.

import Foundation

class Result : NSObject, NSSecureCoding {


    public class var supportsSecureCoding: Bool {true}

    var name: String = "-"

    override init() {
        super.init()
    }

    required init(coder decoder: NSCoder) {
        super.init()
        name = decoder.decodeObject(forKey: "name") as! String
    }
    func encode(with coder: NSCoder) {
        coder.encode(name, forKey: "name")
    }



    class ResultDE: Result {
        override public class var supportsSecureCoding: Bool {true} 

        required init(coder decoder: NSCoder) {
            super.init()
            name = decoder.decodeObject(forKey: "name") as! String
        }
        override func encode(with coder: NSCoder) {
            coder.encode(name, forKey: "name")
        }
    }

}
like image 130
Stephane Gasparini Avatar answered Sep 02 '25 16:09

Stephane Gasparini