skip to Main Content

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")
        }
    }

}

2

Answers


  1. Chosen as BEST ANSWER

    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")
            }
        }
    
    }
    

  2. Maybe you are overthinking this issue. The following code compiles and runs fine:

    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 {
        var title: String = "-"
    
        override init() {
            super.init()
        }
    
        required init(coder decoder: NSCoder) {
            super.init(coder: decoder)
    
            name = decoder.decodeObject(forKey: "title") as! String
        }
        override func encode(with coder: NSCoder) {
            super.encode(with: coder)
    
            coder.encode(name, forKey: "title")
        }
    }
    

    I also added this code which generates a warning, since both classes do implement it"

        let r = Result()
        let r1 = ResultDE()
    
        if let x = r as? NSSecureCoding {
            print("AHA")
        }
        if let x = r1 as? NSSecureCoding {
            print("AHA")
        }
    

    Please note that the subclass calls super for both encode and decode.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search