ios swift swift3 nsuserdefaults nscoding

ios - Intente insertar un objeto de lista que no sea de propiedad al intentar guardar un objeto personalizado en Swift 3



userdefaults in swift (3)

Tengo un objeto simple que se ajusta al protocolo NSCoding .

import Foundation class JobCategory: NSObject, NSCoding { var id: Int var name: String var URLString: String init(id: Int, name: String, URLString: String) { self.id = id self.name = name self.URLString = URLString } // MARK: - NSCoding required init(coder aDecoder: NSCoder) { id = aDecoder.decodeObject(forKey: "id") as? Int ?? aDecoder.decodeInteger(forKey: "id") name = aDecoder.decodeObject(forKey: "name") as! String URLString = aDecoder.decodeObject(forKey: "URLString") as! String } func encode(with aCoder: NSCoder) { aCoder.encode(id, forKey: "id") aCoder.encode(name, forKey: "name") aCoder.encode(URLString, forKey: "URLString") } }

Estoy tratando de guardar una instancia en UserDefaults pero sigue fallando con el siguiente error.

Finalización de la aplicación debido a la excepción no detectada ''NSInvalidArgumentException'', razón: ''Intento de insertar un objeto de lista que no es de propiedad para la categoría de trabajo clave''

Este es el código donde estoy guardando en UserDefaults .

enum UserDefaultsKeys: String { case jobCategory } class ViewController: UIViewController { @IBAction func didTapSaveButton(_ sender: UIButton) { let category = JobCategory(id: 1, name: "Test Category", URLString: "http://www.example-job.com") let userDefaults = UserDefaults.standard userDefaults.set(category, forKey: UserDefaultsKeys.jobCategory.rawValue) userDefaults.synchronize() } }

Reemplacé el valor de enumeración a clave con una cadena normal pero el mismo error aún ocurre. ¿Alguna idea de lo que está causando esto?


Guardar diccionario en usuario predeterminado

let data = NSKeyedArchiver.archivedData(withRootObject: DictionaryData) UserDefaults.standard.set(data, forKey: kUserData)

Recuperando el diccionario

let outData = UserDefaults.standard.data(forKey: kUserData) let dict = NSKeyedUnarchiver.unarchiveObject(with: outData!)as!NSDictionary


JobCategory crear una instancia de Data desde su instancia de JobCategory usando NSKeyedArchiver.archivedData(withRootObject:) y almacenar esa instancia de Data en UserDefaults y luego desarchivar usando NSKeyedUnarchiver.unarchiveObject(with:) , así que intente de esta manera.

Para almacenar datos en UserDefaults

let category = JobCategory(id: 1, name: "Test Category", URLString: "http://www.example-job.com") let encodedData = NSKeyedArchiver.archivedData(withRootObject: category) let userDefaults = UserDefaults.standard userDefaults.set(encodedData, forKey: UserDefaultsKeys.jobCategory.rawValue)

Para recuperar datos de UserDefaults

let decoded = UserDefaults.standard.object(forKey: UserDefaultsKeys.jobCategory.rawValue) as! Data let decodedTeams = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! JobCategory print(decodedTeams.name)


Actualización Swift 4, Xcode 10

He escrito una estructura a su alrededor para facilitar el acceso.

//set, get & remove User own profile in cache struct UserProfileCache { static let key = "userProfileCache" static func save(_ value: Profile!) { UserDefaults.standard.set(try? PropertyListEncoder().encode(value), forKey: key) } static func get() -> Profile! { var userData: Profile! if let data = UserDefaults.standard.value(forKey: key) as? Data { userData = try? PropertyListDecoder().decode(Profile.self, from: data) return userData! } else { return userData } } static func remove() { UserDefaults.standard.removeObject(forKey: key) } }

El perfil es un objeto codificado Json.

struct Profile: Codable { let id: Int! let firstName: String let dob: String! }

Uso:

//save details in user defaults... UserProfileCache.save(profileDetails)

¡¡¡Espero que ayude!!!

Gracias