I was looking for a way to save Structs in the internal storage, until I found a form in the link: https://stackoverflow.com/a/40063878/6566615, I tried it with other Structs that I have and it works correctly, at least Is a possible quick exit to my problem of storing information inside Structs, now my new problem is that the following structure (CoursesG) has parameters, one of them being another Struct. I tried to do it in a fairly structured way based on the methodology described in the link, but I throw an error when trying to save the information.
Struct CursosG & Carreras (in CursosG)
struct CursosG {
let id: Int
let nrc: String
let profesor: String
let carreras: [Carreras]
let dia: String
let bloque: String
let sala: String
let idcurso: Int
let comentario: String
let curso: String
init(id: Int, nrc: String, profesor: String, carreras: [Carreras], dia: String, bloque: String, sala: String, idcurso: Int, comentario: String, curso: String) {
self.id = id
self.nrc = nrc
self.profesor = profesor
self.carreras = carreras
self.dia = dia
self.bloque = bloque
self.sala = sala
self.idcurso = idcurso
self.comentario = comentario
self.curso = curso
}
struct Carreras {
let id: Int
let nombre: String
let semestre: Int
init(id: Int, nombre: String, semestre: Int) {
self.id = id
self.nombre = nombre
self.semestre = semestre
}
}
}
CursosG & Carreras Extensions
extension CursosG {
init?(data: NSData) {
if let coding = NSKeyedUnarchiver.unarchiveObject(with: data as Data) as? Encoding {
id = coding.id as Int
nrc = coding.nrc as String
profesor = coding.profesor as String
carreras = coding.carreras as [Carreras]
dia = coding.dia as String
bloque = coding.bloque as String
sala = coding.sala as String
idcurso = coding.idcurso as Int
comentario = coding.comentario as String
curso = coding.curso as String
} else {
return nil
}
}
func encode() -> NSData {
return NSKeyedArchiver.archivedData(withRootObject: Encoding(self)) as NSData
}
private class Encoding: NSObject, NSCoding {
let id: NSInteger
let nrc: NSString
let profesor: NSString
let carreras: [Carreras]
let dia: NSString
let bloque: NSString
let sala: NSString
let idcurso: NSInteger
let comentario: NSString
let curso: NSString
init(_ CursosG: CursosG) {
id = CursosG.id as NSInteger
nrc = CursosG.nrc as NSString
profesor = CursosG.profesor as NSString
carreras = CursosG.carreras as [Carreras]
dia = CursosG.dia as NSString
bloque = CursosG.bloque as NSString
sala = CursosG.sala as NSString
idcurso = CursosG.idcurso as NSInteger
comentario = CursosG.comentario as NSString
curso = CursosG.curso as NSString
}
public required init?(coder aDecoder: NSCoder) {
if let id = aDecoder.decodeObject(forKey: "id") as? NSInteger { self.id = id } else { return nil }
if let nrc = aDecoder.decodeObject(forKey: "nrc") as? NSString { self.nrc = nrc } else { return nil }
if let profesor = aDecoder.decodeObject(forKey: "profesor") as? NSString { self.profesor = profesor } else { return nil }
if let carreras = aDecoder.decodeObject(forKey: "carreras") as? [Carreras] { self.carreras = carreras } else { return nil }
if let dia = aDecoder.decodeObject(forKey: "dia") as? NSString { self.dia = dia } else { return nil }
if let bloque = aDecoder.decodeObject(forKey: "bloque") as? NSString { self.bloque = bloque } else { return nil }
if let sala = aDecoder.decodeObject(forKey: "sala") as? NSString { self.sala = sala } else { return nil }
if let idcurso = aDecoder.decodeObject(forKey: "idcurso") as? NSInteger { self.idcurso = idcurso } else { return nil }
if let comentario = aDecoder.decodeObject(forKey: "comentario") as? NSString { self.comentario = comentario } else { return nil }
if let curso = aDecoder.decodeObject(forKey: "curso") as? NSString { self.curso = curso } else { return nil }
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: "id")
aCoder.encode(nrc, forKey: "nrc")
aCoder.encode(profesor, forKey: "profesor")
aCoder.encode(carreras, forKey: "carreras")
aCoder.encode(dia, forKey: "dia")
aCoder.encode(bloque, forKey: "bloque")
aCoder.encode(sala, forKey: "sala")
aCoder.encode(idcurso, forKey: "idcurso")
aCoder.encode(comentario, forKey: "comentario")
aCoder.encode(curso, forKey: "curso")
}
}
}
extension CursosG.Carreras {
init?(data: NSData) {
if let coding = NSKeyedUnarchiver.unarchiveObject(with: data as Data) as? Encoding {
id = coding.id as Int
nombre = coding.nombre as String
semestre = coding.semestre as Int
} else {
return nil
}
}
func encode() -> NSData {
return NSKeyedArchiver.archivedData(withRootObject: Encoding(self)) as NSData
}
private class Encoding: NSObject, NSCoding {
let id: NSInteger
let nombre: NSString
let semestre: NSInteger
init(_ Carreras: CursosG.Carreras) {
id = Carreras.id as NSInteger
nombre = Carreras.nombre as NSString
semestre = Carreras.semestre as NSInteger
}
public required init?(coder aDecoder: NSCoder) {
if let id = aDecoder.decodeObject(forKey: "id") as? NSInteger { self.id = id } else { return nil }
if let nombre = aDecoder.decodeObject(forKey: "nombre") as? NSString { self.nombre = nombre } else { return nil }
if let semestre = aDecoder.decodeObject(forKey: "semestre") as? NSInteger { self.semestre = semestre } else { return nil }
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: "id")
aCoder.encode(nombre, forKey: "nombre")
aCoder.encode(semestre, forKey: "semestre")
}
}
}
Save Code
let encoded = CursosAllG.map { $0.encode()}
UserDefaults.standard.set(encoded, forKey: "my-key")
Error Code
2017-02-11 15:53:27.404 Tongoy UCN[30475:714874] -[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x600000486bd0
2017-02-11 15:53:27.491 Tongoy UCN[30475:714874] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x600000486bd0'