NSSecureCoding trouble with collections of custom class

后端 未结 2 1950
渐次进展
渐次进展 2020-12-30 08:08

I am having trouble with adopting NSSecureCoding. I encode an array containing objects of my custom class, which adopts NSSecureCoding properly. When I decode i

相关标签:
2条回答
  • 2020-12-30 08:35

    You've probably already solved this, but I just hit this and found a solution, and thought I'd leave it here for anyone else that finds this.

    My solution was to use decodeObjectOfClasses:forKey:

    In swift:

        if let data = defaults.objectForKey(FinderSyncKey) as? NSData
            let unArchiver = NSKeyedUnarchiver(forReadingWithData: data)
            unArchiver.setRequiresSecureCoding(true)
             //This line is most likely not needed, I was decoding the same object across modules
            unArchiver.setClass(CustomClass.classForCoder(), forClassName: "parentModule.CustomClass")
            let allowedClasses = NSSet(objects: NSArray.classForCoder(),CustomClass.classForCoder())
            if let unarchived = unArchiver.decodeObjectOfClasses(allowedClasses, forKey:NSKeyedArchiveRootObjectKey) as?  [CustomClass]{
                return unarchived
    
            }    
        }
    

    in objective-C it would be something like [unArchiver decodeObjectOfClasses:allowedClasses forKey:NSKeyedArchiveRootObjectKey]

    The change in decode object to decode objects solved the above exception for me.

    0 讨论(0)
  • 2020-12-30 08:44

    I was really struggling with this for an hour in Swift 5.

    My situation was I had a Set of custom Solution objects:

    var resultsSet = Set<Solution>()
    

    Which conformed to Secure Coding:

    static var supportsSecureCoding: Bool{ get{ return true } }
    

    Their container object encoded them as an NSSet, because of Secure Coding:

    aCoder.encode(resultsSet as NSSet, forKey: "resultsSet")
    

    But I always got a complier error during decoding:

    if let decodedResultsSet = aDecoder.decodeObject(of: NSSet.self, forKey: "resultsSet"){
    
                resultsSet = decodedResultsSet as! Set<Solution>
            }
    

    Error:

    2020-02-11 22:35:06.555015+1300 Exception occurred restoring state value for key 'NS.objects' was of unexpected class 'App.Solution'. Allowed classes are '{( NSSet )}'. 2020-02-11 22:35:06.564758+1300 *** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'value for key 'NS.objects' was of unexpected class 'App.Solution'. Allowed classes are '{( NSSet )}'.'

    If I changed the decodeObject(ofClass: to Solution:

    if let decodedResultsSet = aDecoder.decodeObject(of: Solution.self, forKey: "resultsSet"){
    
                resultsSet = decodedResultsSet as! Set<Solution>
            }
    

    I get the error:

    2020-02-11 22:33:46.924580+1300 Exception occurred restoring state value for key 'resultsSet' was of unexpected class 'NSSet'. Allowed classes are '{( app.Solution )}'. 2020-02-11 22:33:46.933812+1300 *** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'value for key 'resultsSet' was of unexpected class 'NSSet'. Allowed classes are '{( app.Solution )}'.'

    The answer, which is obvious now, but I could find it anywhere was to realise the allowed object list is an array, and it needs both NSSet and the custom object: Solution.

    if let decodedResultsSet = aDecoder.decodeObject(of: [NSSet.self, Solution.self], forKey: "resultsSet"){
    
                resultsSet = decodedResultsSet as! Set<Solution>
            }
    

    I hope this helps someone.

    0 讨论(0)
提交回复
热议问题