2014-09-09 10 views
21

I mają następujące kod badania:Swift NSUserDefaults nie zapisuje słownika?

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) 

    } 

Wyjściem println (data0) wynosi zero.

Coś nie tak z moim kodem? Czy Swift Dictionary jest uważany za listę właściwości teraz lub w wersji ostatecznej?

Odpowiedz

30

Aktualizacja Swift 2, Xcode 7: W @atxe zauważył, słowniki NSUserDefaults obecnie odwzorowywane jako [String, AnyObject]. Jest to konsekwencją Objective-C „lekkich rodzajowych”, które pozwalają zadeklarować metodę Objective-C, jak

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

(domyślnych obiektów musi być listami własności, aw szczególności słowniku klucze mogą być tylko ciągi .)

z drugiej strony, Swift słownika mostkiem automatycznie, jeśli to możliwe, więc oryginalny kod od kwestii działa (ponownie):

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) 

Oryginalna odpowiedź dla Swift 1.2: Domyślne ustawienia użytkownika mogą przechowywać obiekty NSDictionary. Są one odwzorowane na Swift jak [NSObject : AnyObject]:

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

i zauważ, że dictionaryForKey() zwraca opcjonalny, więc należy to sprawdzić na przykład z opcjonalnym Zadanie:

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

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

zaraz! kluczem jest jawne zadeklarowanie: var jo: [NSObject: AnyObject] jak wspomniano powyżej. – Sean

+0

Innym sposobem (w przypadku, gdy z jakiegoś powodu nie można podać oświadczenia jawnie) byłoby użycie "jak NSDictionary": userDefaults.setObject ((jo as NSDictionary), forKey: aKey) – winterized

+1

W Swift 2.0 NSUserDefault są zmapowane słowniki jako [String: AnyObject].W rzeczywistości, jeśli spróbujesz zapisać słownik z Int (na przykład) jako klucz, nie powiedzie się on w czasie wykonywania. Możesz zdefiniować swoje rozszerzenie za pomocą silnej metody pisania, aby bezpiecznie wspierać i unikać możliwego błędu w czasie wykonywania, chociaż byłoby miło mieć tak trywialną metodę dostarczoną przez Apple. – atxe

10

Najpierw należy przekonwertować go na NSData. Coś takiego:

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

I w obliczu tego problemu wczoraj i wypełnił radar: Cannot store Dictionary in NSUserDefaults in iOS8. Ten problem dotyczy tylko iOS 8. Opisałem również obejście tego przypadku: Workaround for saving dictionary in NSUserDefaults. Działa jak marzenie.

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

Link do "Obejścia dla zapisywania słownika w NSUserDefaults" jest zepsuty –

1

// swift 4,0

// do zapisywania

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

// dla dla odzyskać

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

Zgodnie z moim rozumowaniem istnieje bardzo mało powodów, aby wywołać 'userDefaults.synchronize()'. – Johan

1

Śledź ten piękny kod poniżej -> 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; 
} 
Powiązane problemy