swift user defaults custom class
cómo guardar y leer array de array en NSUserdefaults en swift? (5)
Necesito crear una matriz para agregar objetos con este formato, como un diccionario en Swift: ["key1": "value1", "key2": "value2"]
Cuando intento guardarlo con NSUserDefaults todo es correcto, pero cuando se lee NSUserDefaults con la clave, esto falla. ¿Qué tipo de datos necesita mi var obj?
let def = NSUserDefaults.standardUserDefaults()
var key = "keySave"
var element: AnyObject!
var array1: [AnyObject!] = []
array1.append(["key1": "val1", "key2": "val2"])
array1.append(["key1": "val1", "key2": "val2"])
//save
var savestring : [AnyObject!]
savestring = array1
var defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(savestring, forKey: key)
defaults.synchronize()
//read
var obj: [AnyObject!] = []
if(obj != nil){
print("size: ")
print(obj.count) //vary long value confused..
element = obj[0] //crash
print(element.objectForKey("key1"))
}
Aquí hay un ejemplo de SNStock leer y escribir una lista de objetos del tipo SNStock que implementa NSCoding : tenemos un acceso para toda la lista, watchlist y dos métodos para agregar y eliminar objetos, es decir, addStock(stock: SNStock) y removeStock(stock: SNStock) .
import Foundation
class DWWatchlistController {
private let kNSUserDefaultsWatchlistKey: String = "dw_watchlist_key"
private let userDefaults: NSUserDefaults
private(set) var watchlist:[SNStock] {
get {
if let watchlistData : AnyObject = userDefaults.objectForKey(kNSUserDefaultsWatchlistKey) {
if let watchlist : AnyObject = NSKeyedUnarchiver.unarchiveObjectWithData(watchlistData as! NSData) {
return watchlist as! [SNStock]
}
}
return []
}
set(watchlist) {
let watchlistData = NSKeyedArchiver.archivedDataWithRootObject(watchlist)
userDefaults.setObject(watchlistData, forKey: kNSUserDefaultsWatchlistKey)
userDefaults.synchronize()
}
}
init() {
userDefaults = NSUserDefaults.standardUserDefaults()
}
func addStock(stock: SNStock) {
var watchlist = self.watchlist
watchlist.append(stock)
self.watchlist = watchlist
}
func removeStock(stock: SNStock) {
var watchlist = self.watchlist
if let index = find(watchlist, stock) {
watchlist.removeAtIndex(index)
self.watchlist = watchlist
}
}
}
Recuerde que su objeto necesita implementar NSCoding o la codificación no funcionará. Aquí se muestra cómo se ve SNStock :
import Foundation
class SNStock: NSObject, NSCoding
{
let ticker: NSString
let name: NSString
init(ticker: NSString, name: NSString)
{
self.ticker = ticker
self.name = name
}
//MARK: NSCoding
required init(coder aDecoder: NSCoder) {
self.ticker = aDecoder.decodeObjectForKey("ticker") as! NSString
self.name = aDecoder.decodeObjectForKey("name") as! NSString
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(ticker, forKey: "ticker")
aCoder.encodeObject(name, forKey: "name")
}
//MARK: NSObjectProtocol
override func isEqual(object: AnyObject?) -> Bool {
if let object = object as? SNStock {
return self.ticker == object.ticker &&
self.name == object.name
} else {
return false
}
}
override var hash: Int {
return ticker.hashValue
}
}
¡Espero que esto ayude!
La pregunta es "array of array" pero creo que la mayoría de la gente probablemente venga aquí solo queriendo saber cómo guardar una matriz en UserDefaults . Para esas personas agregaré algunos ejemplos comunes.
Matriz de cadenas
Guardar matriz
let array = ["horse", "cow", "camel", "sheep", "goat"]
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedStringArray")
Recuperar matriz
let defaults = UserDefaults.standard
let myarray = defaults.stringArray(forKey: "SavedStringArray") ?? [String]()
Matriz Int
Guardar matriz
let array = [15, 33, 36, 723, 77, 4]
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedIntArray")
Recuperar matriz
let defaults = UserDefaults.standard
let array = defaults.array(forKey: "SavedIntArray") as? [Int] ?? [Int]()
Bool array
Guardar matriz
let array = [true, true, false, true, false]
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedBoolArray")
Recuperar matriz
let defaults = UserDefaults.standard
let array = defaults.array(forKey: "SavedBoolArray") as? [Bool] ?? [Bool]()
Date array
Guardar matriz
let array = [Date(), Date(), Date(), Date()]
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedDateArray")
Recuperar matriz
let defaults = UserDefaults.standard
let array = defaults.array(forKey: "SavedDateArray") as? [Date] ?? [Date]()
Matriz de objetos
El objeto personalizado (y en consecuencia las matrices de objetos) UserDefaults un poco más de trabajo para guardar en UserDefaults . Vea los siguientes enlaces para saber cómo hacerlo.
- Guarde objetos personalizados en NSUserDefaults
- Documentos para guardar el color en UserDefaults
- Intentar establecer un objeto que no sea de propiedad como NSUserDefaults
Notas
- El operador nulo coalescente (
??) le permite devolver la matriz guardada o una matriz vacía sin colapsar. Significa que si el objeto devuelve nil, entonces el valor que sigue a??operador se utilizará en su lugar. - Como puede ver, la configuración básica era la misma para
Int,BoolyDate. También lo probé conDouble. Por lo que sé, cualquier cosa que puedas guardar en una lista de propiedades funcionará así.
Prueba esto.
Para obtener los datos de UserDefaults.
var defaults = NSUserDefaults.standardUserDefaults()
var dict : NSDictionary = ["key":"value"]
var array1: NSArray = dict.allValues // Create a dictionary and assign that to this array
defaults.setObject(array1, forkey : "MyKey")
var myarray : NSArray = defaults.objectForKey("MyKey") as NSArray
println(myarray)
Solo para agregar a lo que dice @Zaph en los comentarios.
Tengo el mismo problema que usted, para saber, la matriz de String no se guarda. Aunque Apple une tipos como String y NSString, no pude guardar una matriz de [String] ni de [AnyObject] .
Sin embargo, una matriz de [NSString] funciona para mí.
Entonces su código podría verse así:
let def = NSUserDefaults.standardUserDefaults()
var key = "keySave"
var array1: [NSString] = [NSString]()
array1.append("value 1")
array1.append("value 2")
//save
var defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(array1, forKey: key)
defaults.synchronize()
//read
if let testArray : AnyObject? = defaults.objectForKey(key) {
var readArray : [NSString] = testArray! as [NSString]
}
Tenga en cuenta que he creado una matriz de NSString y no un diccionario. No [NSString : NSString] si funciona con un diccionario, pero probablemente tendrá que definir las cosas como [NSString : NSString] para que funcione.
EDITAR
Vuelve a leer tu pregunta y tu título, estás hablando de una array of array . Creo que mientras te quedes con NSString , una matriz de matriz funcionará. Sin embargo, si crees que mi respuesta es irrelevante, házmelo saber en los comentarios y lo eliminaré.
Swift 4.0
Almacenar:
let arrayFruit = ["Apple","Banana","Orange","Grapes","Watermelon"]
//store in user default
UserDefaults.standard.set(arrayFruit, forKey: "arrayFruit")
Ha podido recuperar:
if let arr = UserDefaults.standard.array(forKey: "arrayFruit") as? [String]{
print(arr)
}