NSKeyedUnarchiver fails to decode a custom object in swift
As Martin pointed out the in the comments, the code works fine in a compiled app, so it's definitely a playground bug.
David, in the comments, suggested to use @objc(User)
in order to get a non-mangled class name, but it didn't help in this specific case, so - as of beta 2 - I still haven't find a workaround to make it work in the playground.
Can't unarchive custom Object with NSKeyedUnarchiver in AR Multiuser
Since here you use Codable
struct ARUser: Codable {
Then
do {
let dataToObject = try JSONDecoder().decode(ARUser.self,from:data)
let objectToData = try JSONEncoder().encode(dataToObject)
}
catch {
print(error)
}
NSKeyedUnarchiver
is an old Objective-C stuff
NSKeyedUnarchiver decodeObjectForKey: cannot decode object of class for key (NS.objects)
It seems that you are mixing up Codable
and NSCoding
. Don't try to use both simultaneously. NSKeyedUnarchiver
belongs to NSCoding
.
Your class contains property list compliant properties. Drop NSCoding
and use only Codable
. (By the way it's recommended to name the class in singular form Product
).
Delete everything which is related to NSCoding
including the protocol conformance and with Codable
it's not necessary that the class must inherit from NSObject
(the object can be even a struct).
The loadProducts
function can be reduced to
func loadProducts() throws -> [Product] {
let data = try Data(contentsOf: Product.ArchiveURL)
return try PropertyListDecoder().decode([Product].self, from: data)
}
It's good practice to hand over thrown
errors to the caller
And delete the CodingKeys
, you don't need them if the keys match the property names.
Can't cast Data from NSKeyedUnarchiver to Object
your error is here:
coder.encode(firstName, forKey: "fisrtName")
typo -> firstName
Swift NSCoding issue with single custom object
The issue was with the guard statments stopping the initialization of the object being unarchived. I changed from guard statements to let statements assigning an empty string if it couldn't decode the value as Michael suggested in the comments above. This helped me find the value that had an improper key so I could update the code. All is well now.
Cannot archive custom class object with NSKeyedArchiver
The NSKeyedArchiver.archivedData(withRootObject:)
method should be used on objects that conform to NSCoding
NOT Codable/Encodable/Decodable
.
If you want your object to implement the Codable
protocol you can use the JSONEncoder
and JSONDecoder
like below to achieve the same thing:
let car = Car(name: "Ferrari")
if let encodedCarData: Data = try? JSONEncoder().encode(car) {
let decodedCar = try? JSONDecoder().decode(Car.self, from: encodedCarData)
}
If you wish to use the NSKeyedArchiver
instead, you can use the example below:
class Car: NSObject, NSSecureCoding {
static var supportsSecureCoding: Bool { return true }
var name: String
init(name: String) {
self.name = name
}
required init?(coder aDecoder: NSCoder) {
guard let name = aDecoder.decodeObject(forKey: "name") as? String else { return nil }
self.name = name
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
}
}
let car = Car(name: "Ferrari")
if let encodedCarData =
try? NSKeyedArchiver.archivedData(withRootObject: car,
requiringSecureCoding: false) {
let decodedCar =
try NSKeyedUnarchiver.unarchivedObject(ofClass: Car.self,
from: encodedCarData)
}
You should also note, archivedData(withRootObject:)
was deprecated in iOS 12.0 and you should use +archivedDataWithRootObject:requiringSecureCoding:error:
instead.
Related Topics
Swift: Lazily Encapsulating Chains of Map, Filter, Flatmap
Swift and Objectmapper: Nsdate with Min Value
What Is the Markup Format for Documentation on the Parameters of a Block in Swift
How Does Let X Where X.Hassuffix("Pepper") Work
Com.Apple.Itunes Aedeterminepermissiontoautomatetarget Is Always Return -600
Changing Nav Bar Item Programmatically in Swift
How to Test an Optionset with a Switch Statement
Testing Protocol Conformance with Associated Types
Nspopover to Start in a Detached State
Not Getting Expected Delegate Calls When Trying to Restore In-App Purchases with Storekit
How to Give PDF Data a Filename for User to Save in Swift
A Codable Structure Contains a Protocol Property
How to Load the Photo Library into Uicollectionview? Swift
Using Structs (Bytes) with Swift - Struct to Nsdata and Nsdata to Struct
How to Get Distinct Results from a Single Field in Core Data (Swift 4)