web-dev-qa-db-fra.com

comment sauvegarder et lire un tableau de tableau dans NSUserdefaults en rapide?

J'ai besoin de créer un tableau pour ajouter des objets avec ce format comme un dictionnaire dans Swift: ["key1": "value1", "key2": "value2"]

Lorsque j'essaie de l'enregistrer avec NSUserDefaults tout est correct, mais lorsque lu NSUserDefaults avec la clé, cela se bloque. De quel type de données mon var obj a-t-il besoin?

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"))
}
68
user3745888

La question se lit "tableau de tableau" mais je pense que la plupart des gens viennent probablement ici juste pour savoir comment sauvegarder un tableau sur UserDefaults. Pour ces personnes, je vais ajouter quelques exemples courants.

Tableau de chaînes

Enregistrer le tableau

let array = ["horse", "cow", "camel", "sheep", "goat"]

let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedStringArray")

Récupérer un tableau

let defaults = UserDefaults.standard
let myarray = defaults.stringArray(forKey: "SavedStringArray") ?? [String]()

Tableau Int

Enregistrer le tableau

let array = [15, 33, 36, 723, 77, 4]

let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedIntArray")

Récupérer un tableau

let defaults = UserDefaults.standard
let array = defaults.array(forKey: "SavedIntArray")  as? [Int] ?? [Int]()

Tableau de Bool

Enregistrer le tableau

let array = [true, true, false, true, false]

let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedBoolArray")

Récupérer un tableau

let defaults = UserDefaults.standard
let array = defaults.array(forKey: "SavedBoolArray")  as? [Bool] ?? [Bool]()

Date tableau

Enregistrer le tableau

let array = [Date(), Date(), Date(), Date()]

let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedDateArray")

Récupérer un tableau

let defaults = UserDefaults.standard
let array = defaults.array(forKey: "SavedDateArray")  as? [Date] ?? [Date]()

Tableau d'objets

Les objets personnalisés (et par conséquent les tableaux d’objets) demandent un peu plus de travail pour enregistrer dans UserDefaults. Voir les liens suivants pour savoir comment le faire.

Remarques

  • L’opérateur de coalescence nul (??) vous permet de retourner le tableau enregistré ou un tableau vide sans planter. Cela signifie que si l'objet renvoie nil, la valeur suivant le ?? opérateur sera utilisé à la place.
  • Comme vous pouvez le constater, la configuration de base était la même pour Int, Bool et Date. Je l'ai aussi testé avec Double. Autant que je sache, tout ce que vous pouvez enregistrer dans une liste de propriétés fonctionnera comme ceci.
150
Suragch

Juste pour ajouter à ce que @Zaph dit dans les commentaires.

J'ai le même problème que vous, à savoir, le tableau de String n'est pas enregistré. Même si Apple relie des types tels que String et NSString, je n’ai pas pu enregistrer un tableau de [String] ni de [AnyObject].

Cependant, un tableau de [NSString] travaille pour moi.

Donc, votre code pourrait ressembler à ça:

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]
}

Notez que j'ai créé un tableau de NSString et non un dictionnaire. Je n'ai pas vérifié si cela fonctionnait avec un dictionnaire, mais vous devrez probablement définir les choses comme [NSString : NSString] le faire fonctionner.

EDIT

Relisant votre question et votre titre, vous parlez de array of array. Je pense que tant que vous restez avec NSString, un tableau de tableau fonctionnera. Cependant, si vous pensez que ma réponse n'est pas pertinente, faites-le moi savoir dans les commentaires et je vais l'enlever.

16
HpTerm

Voici un exemple de lecture et d’écriture d’une liste d’objets de type SNStock qui implémente NSCoding - nous disposons d’un accesseur pour la liste complète, watchlist et de deux méthodes pour l’ajouter. et supprimez les objets, c’est-à-dire addStock(stock: SNStock) et 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
    }
  }

}

Rappelez-vous que votre objet doit implémenter NSCoding sinon l'encodage ne fonctionnera pas. Voici à quoi ressemble 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
  }
}

J'espère que cela t'aides!

11
Zorayr

Essaye ça.

Pour obtenir les données 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)
3
Alvin Varghese

Swift 4.

Magasin:

let arrayFruit = ["Apple","Banana","Orange","Grapes","Watermelon"]    

 //store in user default
 UserDefaults.standard.set(arrayFruit, forKey: "arrayFruit")

chercher:

if let arr = UserDefaults.standard.array(forKey: "arrayFruit") as? [String]{
        print(arr)
    }
2
Mr.Javed Multani