Cannot decode object of class

后端 未结 5 1670
难免孤独
难免孤独 2020-12-08 04:54


I am trying to send a \"Class\" to my Watchkit extension but I get this error.

* Terminating app due to uncaught exception \'NSInvalidUna

5条回答
  •  甜味超标
    2020-12-08 05:09

    I had a similar situation where my app used my Core framework in which I kept all model classes. E.g. I stored and retrieved UserProfile object using NSKeyedArchiver and NSKeyedUnarchiver, when I decided to move all my classes to MyApp NSKeyedUnarchiver started throwing errors because the stored objects were like Core.UserProfile and not MyApp.UserProfile as expected by the unarchiver. How I solved it was to create a subclass of NSKeyedUnarchiver and override classforClassName function:

    class SKKeyedUnarchiver: NSKeyedUnarchiver {
        override open func `class`(forClassName codedName: String) -> Swift.AnyClass? {
            let lagacyModuleString = "Core."
            if let range = codedName.range(of: lagacyModuleString), range.lowerBound.encodedOffset == 0  {
                return NSClassFromString(codedName.replacingOccurrences(of: lagacyModuleString, with: ""))
            }
            return NSClassFromString(codedName)
        }
    }
    

    Then added @objc(name) to classes which needed to be archived, as suggested in one of the answers here.

    And call it like this:

    if let unarchivedObject = SKKeyedUnarchiver.unarchiveObject(withFile: UserProfileServiceImplementation.archiveURL.path) as? UserProfile {
        currentUserProfile = unarchivedObject
    }
    

    It worked very well.

    The reason why the solution NSKeyedUnarchiver.setClass(YourClassName.self, forClassName: "YourClassName") was not for me because it doesn't work for nested objects such as when UserProfile has a var address: Address. Unarchiver will succeed with the UserProfile but will fail when it goes a level deeper to Address.

    And the reason why the @objc(name) solution alone didn't do it for me was because I didn't move from OBJ-C to Swift, so the issue was not UserProfile -> MyApp.UserProfile but instead Core.UserProfile -> MyApp.UserProfile.

提交回复
热议问题