Фактическая ошибка, которую вы получаете:
- [_ SwiftValue encodeWithCoder:]: нераспознанный селектор, отправленный экземпляру
И это исходит из строки:
aCoder.encode(more, forKey: "more")
Причина проблемы заключается в том, что more
(типа Unward
) не соответствует NSCoding
.Но Swift struct
не может соответствовать NSCoding
.Вам нужно изменить Unward
на класс, который расширяет NSObject
в дополнение к соответствию NSCoding
.Ничто из этого не влияет на способность соответствовать Codable
.
Вот ваши обновленные классы:
class Unward: NSObject, Codable, NSCoding {
var id: Int
var job: String
init(id: Int, job: String) {
self.id = id
self.job = job
}
func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: "id")
aCoder.encode(job, forKey: "job")
}
required init?(coder aDecoder: NSCoder) {
id = aDecoder.decodeInteger(forKey: "id")
job = aDecoder.decodeObject(forKey: "job") as? String ?? ""
}
}
class Akward: NSObject, Codable, NSCoding {
var name: String
var more: Unward
init(name: String, more: Unward) {
self.name = name
self.more = more
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(more, forKey: "more")
}
required init?(coder aDecoder: NSCoder) {
name = aDecoder.decodeObject(forKey: "name") as? String ?? ""
more = aDecoder.decodeObject(forKey: "more") as? Unward ?? Unward(id: -1, job: "unk")
}
}
И ваши тестовые значения:
var upone = Unward(id: 12, job: "testing")
var adone = Akward(name: "Adrian", more: upone)
Теперь вы можетеархив и разархивирование:
let encodeit = NSKeyedArchiver.archivedData(withRootObject: adone)
let redone = NSKeyedUnarchiver.unarchiveObject(with: encodeit) as! Akward
И вы можете кодировать и декодировать:
let enc = try! JSONEncoder().encode(adone)
let dec = try! JSONDecoder().decode(Akward.self, from: enc)