ios - standard - Guardar objetos personalizados en NSUserDefaults
userdefaults swift 4 (2)
Esta pregunta ya tiene una respuesta aquí:
Tengo un
ViewController
noticias y un
TeamViewController
.
TeamViewController
contiene una tableView de teamObjects que, cuando se selecciona, se agrega a la matriz.
Quiero agregar esta matriz a
NSUserDefaults
para poder acceder a ellos desde
NewsController
que contiene una solicitud de URL donde se necesitan los teamObjects.
Sin embargo, sigo obteniendo:
''Intente insertar un objeto de lista que no sea de propiedad ("") para equipos clave''
Estoy abierto a otras sugerencias si hay mejores formas que almacenarlo en
NSUserDefaults
Método
didSelectRowAtIndexPath
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let team = self.teamArray[indexPath.row] as Team
var removed = false
for (index, value) in enumerate(self.teamSelected) {
if (value == team) {
self.teamSelected.removeAtIndex(index)
removed = true
}
}
if (!removed) {
self.teamSelected.append(team)
}
var userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setValue(self.teamSelected, forKey: "teams")
userDefaults.synchronize()
tableView.reloadData()
}
Mi objeto
class Team: NSObject{
var id: Int!
var name: NSString!
var shortname: NSString!
init(id: Int, name:NSString, shortname: NSString) {
self.id = id
self.name = name
self.shortname = shortname
}
}
En realidad, necesitará archivar el objeto personalizado en
NSData
luego guardarlo en los valores predeterminados del usuario y recuperarlo de los valores predeterminados del usuario y desarchivarlo nuevamente.
Puedes archivarlo así
let teams = [Team(id: 1, name: "team1", shortname: "t1"), Team(id: 2, name: "team2", shortname: "t2")]
var userDefaults = UserDefaults.standard
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: teams)
userDefaults.set(encodedData, forKey: "teams")
userDefaults.synchronize()
y desarchivarlo así
let decoded = userDefaults.data(forKey: "teams")
let decodedTeams = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Team]
Pero si acabas de hacer eso obtendrás
.Team encodeWithCoder:]: unrecognized selector sent to instance
Tendrás que hacer que Team se ajuste a NSCoding así
class Team: NSObject, NSCoding {
var id: Int
var name: String
var shortname: String
init(id: Int, name: String, shortname: String) {
self.id = id
self.name = name
self.shortname = shortname
}
required convenience init(coder aDecoder: NSCoder) {
let id = aDecoder.decodeInteger(forKey: "id")
let name = aDecoder.decodeObject(forKey: "name") as! String
let shortname = aDecoder.decodeObject(forKey: "shortname") as! String
self.init(id: id, name: name, shortname: shortname)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: "id")
aCoder.encode(name, forKey: "name")
aCoder.encode(shortname, forKey: "shortname")
}
}
Puedes probar NSKeyedUnarchiver , como a continuación
Aquí almacené el objeto UIColor en UserDefault Puede cambiarlo con su objeto
NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"myColor"];
y para recuperar eso
NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"myColor"];
UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];
Nota: Este es el objetivo C, pero espero que pueda convertir esto en Swift
Espero que esto resuelva tu problema