2014-09-09 27 views
21

Ho il seguente codice di prova:Swift NSUserDefaults non salva il dizionario?

func testSaveDictionary() { 
    let userDefaults = NSUserDefaults.standardUserDefaults() 
    var jo = [ 
     "a" : "1.0", 
     "b" : "2.0" 
    ] 

    let akey = "aKey" 
    userDefaults.setObject(jo, forKey: akey) 
    var isOk = userDefaults.synchronize() 

    var data0 = userDefaults.dictionaryForKey(akey) 
    println(data0) 

    } 

L'uscita del println (data0) è nullo.

Qualcosa non va nel mio codice? Il dizionario Swift ha preso in considerazione l'elenco delle proprietà ora o nella versione finale?

risposta

30

Aggiornamento per Swift 2, Xcode 7: Come @atxe notato, dizionari NSUserDefaults ora sono mappati come [String, AnyObject]. Si tratta di una conseguenza della Objective-C "generici leggeri" che consentono per dichiarare il metodo Objective-C come

- (NSDictionary<NSString *,id> *)dictionaryForKey:(NSString *)defaultName 

(oggetti di default deve essere elenchi di proprietà e, in particolare, il dizionario chiavi possono essere solo le stringhe .)

D'altra parte, un dizionario di Swift è colmato automaticamente, se possibile, in modo che il codice originale dalla questione lavora (di nuovo):

let jo = [ 
    "a" : "1.0", 
    "b" : "2.0" 
] 

let akey = "aKey" 
// Swift 2: 
userDefaults.setObject(jo, forKey: akey) 
// Swift 3: 
userDefaults.set(jo, forKey: akey) 

Risposta originale per Swift 1.2: Le impostazioni predefinite dell'utente possono memorizzare gli oggetti NSDictionary. Questi sono mappati Swift come [NSObject : AnyObject]:

var jo : [NSObject : AnyObject] = [ 
    "a" : "1.0", 
    "b" : "2.0" 
] 
userDefaults.setObject(jo, forKey: akey) 
var isOk = userDefaults.synchronize() 

e si noti che dictionaryForKey() restituisce un optional, così si dovrebbe controllare ad esempio, con un incarico optional:

if let data0 = userDefaults.dictionaryForKey(akey) { 
    print(data0) 
} else { 
    print("not set") 
} 

// Output: [b: 2.0, a: 1.0] 
+2

proprio sopra! la chiave è dichiarare esplicitamente: var jo: [NSObject: AnyObject] come menzionato sopra. – Sean

+0

Un altro modo (se per qualche motivo non è possibile rendere esplicita la dichiarazione) è utilizzare "come NSDictionary": userDefaults.setObject ((jo come NSDictionary), forKey: aKey) – winterized

+1

In Swift 2.0 NSUserDefault i dizionari sono mappati come [String: AnyObject].In realtà se provi a salvare un dizionario con Int (ad esempio) come chiave, fallisce in runtime. Puoi definire la tua estensione con un metodo fortemente tipizzato per supportare in sicurezza ed evitare un possibile errore di runtime, sebbene sarebbe bello avere un metodo così banale fornito da Apple. – atxe

10

È necessario convertirlo prima in NSData. Qualcosa di simile a questo:

var data = NSKeyedArchiver.archivedDataWithRootObject(jo) 
var userDefaults = NSUserDefaults.standardUserDefaults() 
userDefaults.setObject(data, forKey:akey) 
3

Ho affrontato questo problema ieri e ha presentato un radar: Cannot store Dictionary in NSUserDefaults in iOS8. Questo problema è relativo solo a iOS 8. Inoltre ho descritto una soluzione alternativa per questo caso: Workaround for saving dictionary in NSUserDefaults. Funziona come un fascino.

/// Save 
NSUserDefaults.standardUserDefaults().setObject(NSKeyedArchiver.archivedDataWithRootObject(object), forKey: key) 

/// Read 
var data = NSUserDefaults.standardUserDefaults().objectForKey(key) as NSData 
var object = NSKeyedUnarchiver.unarchiveObjectWithData(data) as [String: String] 
+3

Il collegamento a "Soluzione temporanea per il salvataggio del dizionario in NSUserDefaults" è rotto –

1

// rapida 4,0

// per il salvataggio

let userDefaults = UserDefaults.standard 
    userDefaults.setValue(value, forKey: "Your_Key") 
    userDefaults.synchronize() 

// per per recuperare

 let loadedCart = UserDefaults.standard.dictionary(forKey: "Your_Key") 
+0

Secondo la mia comprensione ci sono pochissimi motivi per chiamare 'userDefaults.synchronize()'. – Johan

1

Seguire questa bella codice qui sotto -> Swift 3

public func setDict(dict: NSDictionary) { 
    let data = NSKeyedArchiver.archivedData(withRootObject: dict) 
    let userDefaults = UserDefaults.standard 
    userDefaults.set(data, forKey:"keyHere") 
} 


public func getDict() -> NSDictionary { 
    let data = UserDefaults.standard.object(forKey: "keyHere") as! NSData 
    let object = NSKeyedUnarchiver.unarchiveObject(with: data as Data) as! NSDictionary 
    return object; 
} 
Problemi correlati