Reputation: 2897
I have a JSON file I am reading from disk
This is the structure of the file:
[
{
"name": "3X",
"priority": 33
},
{
"name": "4X",
"priority": 32
}
]
I am decoding it to a class called Test
class TestClass: NSObject, Codable {
enum CodingKeys: String, CodingKey {
case name, priority
}
let name:String
let priority:Int
var optional:String? = nil
var problem:String = "eli"
init(name:String, priority:Int, optional:String? = nil, problem:String) {
self.name = name
self.priority = priority
self.optional = optional
self.problem = problem
super.init()
}
}
This is the code I am using to decode the file
if let path = Bundle.main.path(forResource: "test", ofType: "json") {
do {
let jsonData = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let testObjects = try JSONDecoder().decode([TestClass].self, from: jsonData)
let data = try! NSKeyedArchiver.archivedData(withRootObject: testObjects, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "test_objects")
} catch {
// error in parsing json
}
}
After decoding I am trying to save the array into disk, I am converting it into NSData for saving however NSKeyedArchiver.archivedData
fails with the following error:
{NSDebugDescription=Caught exception during archival: -[BugTesting.TestClass encodeWithCoder:]: unrecognized selector sent to instance 0x600002119ac0
To me this looks very strange since I am conforming to Codable
.
Any help would be appreciated.
Upvotes: 1
Views: 718
Reputation: 437682
If you want to encode this, I might suggest PropertyListEncoder
. Then you don’t need to introduce the NSObject
(nor the NSCoding
/NSSecureCoding
cruft) associated with NSKeyedArchiver
:
class TestClass: Codable {
enum CodingKeys: String, CodingKey {
case name, priority
}
let name: String
let priority: Int
var optional: String?
var problem: String?
init(name: String, priority: Int, optional: String? = nil, problem: String? = nil) {
self.name = name
self.priority = priority
self.optional = optional
self.problem = problem
}
}
Then to encode:
let data = try PropertyListEncoder().encode(test)
And to decode:
let test2 = try PropertyListDecoder().decode(TestClass.self, from: data)
I’m not sure why you wouldn’t encode optional
or problem
. I’d probably be inclined to code those too, unless there was some reason why you wanted to lose that data during the encoding/decoding process. If you want all the properties encoded, you can just eliminate the CodingKeys
:
class TestClass: Codable {
let name: String
let priority: Int
var optional: String?
var problem: String?
init(name: String, priority: Int, optional: String? = nil, problem: String? = nil) {
self.name = name
self.priority = priority
self.optional = optional
self.problem = problem
}
}
Upvotes: 2