Pensé que sabía qué estaba causando este error, pero parece que no puedo entender qué hice mal.
Aquí está el mensaje de error completo que recibo:
Intente establecer un objeto de lista que no sea de propiedad ( "<BC_Person: 0x8f3c140>" ) como un valor NSUserDefaults para personDataArray clave
Tengo una Personclase que creo que se ajusta al NSCodingprotocolo, donde tengo ambos métodos en mi clase de persona:
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.personsName forKey:@"BCPersonsName"];
[coder encodeObject:self.personsBills forKey:@"BCPersonsBillsArray"];
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
self.personsName = [coder decodeObjectForKey:@"BCPersonsName"];
self.personsBills = [coder decodeObjectForKey:@"BCPersonsBillsArray"];
}
return self;
}
En algún momento de la aplicación, se establece NSStringin BC_PersonClass, y tengo una DataSaveclase que creo que está manejando la codificación de las propiedades en mi BC_PersonClass. Aquí está el código que estoy usando de la DataSaveclase:
- (void)savePersonArrayData:(BC_Person *)personObject
{
// NSLog(@"name of the person %@", personObject.personsName);
[mutableDataArray addObject:personObject];
// set the temp array to the mutableData array
tempMuteArray = [NSMutableArray arrayWithArray:mutableDataArray];
// save the person object as nsData
NSData *personEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:personObject];
// first add the person object to the mutable array
[tempMuteArray addObject:personEncodedObject];
// NSLog(@"Objects in the array %lu", (unsigned long)mutableDataArray.count);
// now we set that data array to the mutable array for saving
dataArray = [[NSArray alloc] initWithArray:mutableDataArray];
//dataArray = [NSArray arrayWithArray:mutableDataArray];
// save the object to NS User Defaults
NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
[userData setObject:dataArray forKey:@"personDataArray"];
[userData synchronize];
}
Espero que sea suficiente código para darte una idea de lo que estoy tratando de hacer. Una vez más, sé que mi problema radica en cómo estoy codificando mis propiedades en mi clase BC_Person, parece que no puedo entender qué estoy haciendo mal.
¡Gracias por la ayuda!
fuente

that I think is conforming to the NSCoding protocoles muy fácil agregar pruebas unitarias para eso, y realmente vale la pena.Respuestas:
El código que publicó intenta guardar una matriz de objetos personalizados en
NSUserDefaults. No puedes hacer eso. Implementar losNSCodingmétodos no ayuda. Sólo se puede almacenar cosas comoNSArray,NSDictionary,NSString,NSData,NSNumber, yNSDateenNSUserDefaults.Necesita convertir el objeto a
NSData(como lo tiene en algunos de los códigos) y almacenarloNSDataenNSUserDefaults. Incluso puede almacenar unaNSArraydeNSDatasi es necesario.Cuando vuelva a leer la matriz, debe desarchivar el
NSDatapara recuperar susBC_Personobjetos.Quizás quieras esto:
fuente
NSMutableArrayse extiendeNSArray. Está perfectamente bien pasar unNSMutableArraya cualquier método que espere unNSArray. Tenga en cuenta que la matriz realmente almacenadaNSUserDefaultsserá inmutable cuando la vuelva a leer.Me parece un desperdicio ejecutar la matriz y codificar los objetos en NSData usted mismo. Su error
BC_Person is a non-property-list objectle dice que el marco no sabe cómo serializar su objeto persona.Por lo tanto, todo lo que se necesita es garantizar que su objeto personal se ajuste a NSCoding, luego simplemente puede convertir su matriz de objetos personalizados en NSData y almacenarlos en los valores predeterminados. Aquí hay un patio de recreo:
Editar : la escritura
NSUserDefaultsen Xcode 7 no funciona, por lo que el área de juegos archivará los datos y volverá a imprimir una salida. El paso UserDefaults se incluye en caso de que se solucione en un punto posteriorY Voila, ha almacenado una matriz de objetos personalizados en NSUserDefaults
fuente
func encode(with aCoder: NSCoder)Ahorrar:
Llegar:
Para eliminar
fuente
Solución Swift 3
Clase de utilidad simple
Clase de modelo
Como llamar
fuente
Swift- 4 Xcode 9.1
prueba este código
no puede almacenar el asignador en NSUserDefault, solo puede almacenar NSData, NSString, NSNumber, NSDate, NSArray o NSDictionary.
fuente
En primer lugar, la respuesta de rmaddy (arriba) es correcta: la implementación
NSCodingno ayuda. Sin embargo, debe implementarNSCodingpara usarNSKeyedArchivery todo eso, por lo que es solo un paso más ... convertir a través deNSData.Métodos de ejemplo
Así se puede envolver sus
NSCodingobjetos en unaNSArrayoNSDictionaryo lo que sea ...fuente
Tuve este problema al intentar guardar un diccionario en
NSUserDefaults. Resulta que no se guardaría porque conteníaNSNullvalores. Así que simplemente copié el diccionario en un diccionario mutable, eliminé los valores nulos y luego los guardé enNSUserDefaultsEn este caso, sabía qué claves podrían ser
NSNullvalores.fuente
La estructura Pref es un contenedor personalizado alrededor del objeto estándar UserDefaults.
Entonces puedes usarlo de esta manera:
fuente
if let data = UserDefaults.standard.data(forKey: keyUser) {y por cierto, el lanzamiento deUsera noUsertiene sentido simplementereturn try JSONDecoder().decode(User.self, from: data)Rápido con
@propertyWrapperGuardar
Codableobjeto enUserDefaultEjemplo de modelo de usuario confirmar Codificable
Cómo usarlo
fuente
fuente
Swift 5 Muy fácil
fuente