Wie speichere und lese ich ein Array von Arrays in NSUserdefaults in Swift?

81

Ich muss ein Array erstellen, um Objekte mit diesem Format wie ein Wörterbuch in Swift hinzuzufügen: ["key1": "value1", "key2": "value2"]

Wenn ich versuche, es mit NSUserDefaultsallem zu speichern, ist das richtig, aber wenn ich NSUserDefaultsmit dem Schlüssel lese, stürzt dies ab. Welche Art von Daten benötigt mein 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"))
}
user3745888
quelle
3
Es sieht so aus, als ob NSUserDefaults String verarbeiten kann, nicht jedoch Array und Dictionary. Dies funktioniert nur für die NS * -Typen, die die Dokumente beschreiben. Das sieht also nach einem Fehler in Swift aus.
Zaph
Um ein wenig über das hinauszugehen, was @Zaph sagt, habe ich mit [String] getestet und es funktioniert nicht, aber es funktioniert mit [NSString]. Überprüfen Sie meine Antwort.
HpTerm

Antworten:

211

Die Frage lautet "Array of Array", aber ich denke, die meisten Leute kommen wahrscheinlich hierher, um zu wissen, wie man ein Array speichert UserDefaults. Für diese Leute werde ich einige allgemeine Beispiele hinzufügen.

String-Array

Array speichern

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

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

Array abrufen

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

Int Array

Array speichern

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

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

Array abrufen

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

Bool-Array

Array speichern

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

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

Array abrufen

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

Datumsarray

Array speichern

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

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

Array abrufen

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

Objektarray

Benutzerdefinierte Objekte (und folglich Arrays von Objekten) erfordern etwas mehr Arbeit zum Speichern UserDefaults. Informationen dazu finden Sie unter den folgenden Links.

Anmerkungen

  • Mit dem Null-Koaleszenz-Operator ( ??) können Sie das gespeicherte Array oder ein leeres Array ohne Absturz zurückgeben. Dies bedeutet, dass, wenn das Objekt Null zurückgibt, der Wert nach dem folgt?? stattdessen Operator verwendet wird .
  • Wie Sie sehen können, war die Basis - Setup das gleiche für Int, Boolund Date. Ich habe es auch mit getestetDouble . Soweit ich weiß, funktioniert alles, was Sie in einer Eigenschaftsliste speichern können, so.
Suragch
quelle
16

Nur um das zu ergänzen, was @Zaph in den Kommentaren sagt.

Ich habe das gleiche Problem wie Sie, um zu wissen, dass das Array von Stringnicht gespeichert wird. Obwohl Apple Typen wie String und NSString überbrückt, konnte ich kein Array von [String]beiden speichern[AnyObject] .

Jedoch eine Reihe von [NSString] funktioniert Arbeiten für mich.

Ihr Code könnte also so aussehen:

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

Beachten Sie, dass ich ein Array von NSString und kein Wörterbuch erstellt habe. Ich habe nicht überprüft, ob es mit einem Wörterbuch funktioniert, aber wahrscheinlich müssen Sie die Dinge als definieren[NSString : NSString] , dass es funktioniert.

BEARBEITEN

Lesen Sie Ihre Frage und Ihren Titel noch einmal durch array of array. Ich denke das, solange du bei bleibstNSString , wird ein Array von Arrays funktionieren. Wenn Sie jedoch der Meinung sind, dass meine Antwort irrelevant ist, lassen Sie es mich einfach in den Kommentaren wissen und ich werde sie entfernen.

HpTerm
quelle
11

Hier ist ein Beispiel für das Lesen und Schreiben einer Liste von Objekten des Typs SNStock, der implementiert wird. NSCodingWir haben einen Accessor für die gesamte Liste watchlistund zwei Methoden zum Hinzufügen und Entfernen von Objekten, nämlich addStock(stock: SNStock)und 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
    }
  }

}

Denken SieNSCoding daran, dass Ihr Objekt implementiert werden muss, da sonst die Codierung nicht funktioniert. So SNStocksieht es aus:

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

Hoffe das hilft!

Zorayr
quelle
3

Versuche dies.

Um die Daten aus den UserDefaults abzurufen.

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)
Alvin Varghese
quelle
Ich füge var dict hinzu: [AnyObject!] = [] Und var array1: NSArray = dict, aber das ist leer. Wie kann man das richtig machen?
user3745888
@AlvinVarghese Versuchen Sie tatsächlich den Code. Es gibt einen Tippfehler, und selbst wenn dieser behoben ist, wird nur ein Array mit einem Eintrag gespeichert: "Wert".
Zaph
3

Swift 4.0

Geschäft:

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

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

Holen:

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

Hier ist:

var array : [String] = ["One", "Two", "Three"]
let userDefault = UserDefaults.standard
// set
userDefault.set(array, forKey: "array")
// retrieve 
if let fetchArray = userDefault.array(forKey: "array") as? [String] {
    // code 
}
Andrei Levchenko
quelle
0

Wenn Sie mit Swift 5+ arbeiten , müssen Sie verwenden UserDefaults.standard.setValue(value, forKey: key)und gespeicherte Daten erhalten, die Sie verwenden müssen UserDefaults.standard.dictionary(forKey: key).

Wimukthi Rajapaksha
quelle