2017-01-25 8 views
1

辞書にキーと値を追加しようとしているときに、この辞書を追加してユーザーがデフォルトし、辞書オブジェクトに読み戻そうとしています。ユーザーのデフォルトで辞書の内容がすぐに保存されない3

1)辞書がユーザーのデフォルトから空になっているのはなぜですか?2つの質問があります。辞書にキーと値を追加したので、辞書に保存してはいけません。ユーザーのデフォルトから検索しますか?私はこのコードために何ができるか

let defaults = UserDefaults.standard; 
var myDict = [String: String]() 
myDict["key"] = "value" 

defaults.setValue(myDict, forKey: "myDict") 


let mydict2 = defaults.object(forKey: "myDict") as? [String: String] ?? [String:String]() 
print(mydict2) 

2)辞書店であれば辞書は、このようなものだったので、もし私が値またはキーとして作成したカスタムクラス:どのように私ができる

class Car { 
    var engineSize: Int 
    var color: String 

    init() { 
    engineSize = 2000 
    color = "blue" 
    } 

} 

class Boat {  
    var surfaceArea: Int 
    var weight: Int 

    init() {  
    surfaceArea = 3500 
    weight = 4000 
    } 
} 

var myDict = [Car: Boat]() 

をその2番目のdictをユーザーのデフォルト値に保存し、そこから読み込みます。

ありがとう

EDIT:

これはebby94によって提案された答えです:

var myDict = [String:String]() 
myDict["key"] = "value"; 

let data = NSKeyedArchiver.archivedData(withRootObject: myDict) 
UserDefaults.standard.set(data, forKey: "myDict") 


func foo() 

{ 
    guard let archivedData = UserDefaults.standard.value(forKey: "myDict") as? Data 
    else 
    { 
     print("failed1") 
     return 
    } 
    guard var unarchivedDictionary = NSKeyedUnarchiver.unarchiveObject(with: archivedData) as? [String:String] 
    else 
    { 
     print("failed2") 
     return 
    } 

    print(unarchivedDictionary["key"]!) 
} 

foo() 

しかし、これは私が正しくデータがアーカイブされていなかったと仮定しています、failed1を印刷します。私はそれを遊び場で走っているからでしょうか?

+1

まず、実際のプロジェクトでテストしてみてください(遊び場は動作しません) –

+1

次に、クラスをNSCodingに準拠させる必要があります。 –

+1

3回目の使用KeyedArchieverでオブジェクトをデータに変換する –

答えて

3

カスタムオブジェクトをuserDefaultに保存する場合は、最初に&をデコードしてから変数&を保存して保存する必要があります。

class Car { 
    var engineSize: Int 
    var color: String 

    init() { 
     engineSize = 2000 
     color = "blue" 
    } 
    // Decode 
    required convenience public init(coder decoder: NSCoder) 
    { 
     self.init() 

     if let engineSize = decoder.decodeObject(forKey: "engineSize") as? Int 
     { 
      self.engineSize = engineSize 
     } 
     if let color = decoder.decodeObject(forKey: "color") as? String 
     { 
      self.color = color 
     } 
    } 

    // Encode 
    func encodeWithCoder(coder : NSCoder) 
    { 
     if let engineSize = self.engineSize 
     { 
      coder.encode(engineSize, forKey: "engineSize") 
     } 
     if let color = self.color 
     { 
      coder.encode(color, forKey: "weight") 
     } 
    } 
} 

class Boat { 
    var surfaceArea: Int 
    var weight: Int 

    init() { 
     surfaceArea = 3500 
     weight = 4000 
    } 

    // Decode 
    required convenience public init(coder decoder: NSCoder) 
    { 
     self.init() 

     if let surfaceArea = decoder.decodeObject(forKey: "surfaceArea") as? Int 
     { 
      self.surfaceArea = surfaceArea 
     } 
     if let weight = decoder.decodeObject(forKey: "weight") as? Int 
     { 
      self.weight = weight 
     } 
    } 

    // Encode 
    func encodeWithCoder(coder : NSCoder) 
    { 
     if let surfaceArea = self.surfaceArea 
     { 
      coder.encode(surfaceArea, forKey: "surfaceArea") 
     } 
     if let weight = self.weight 
     { 
      coder.encode(weight, forKey: "weight") 
     } 
    } 
+0

お返事ありがとうございました。とにかくコードをもう少し説明することができますか?これは多くのことが私には新しく、私はそれを使い始める前にそれを丁寧に理解したいと思います。利便性が求められるのは何ですか? self.surfaceArea = surfaceAreaは自己のデコーダのオブジェクトですか? –

2

UserDefaultsに直接辞書を保存することはできません。辞書をデータに変換して保存し、データを取り出して辞書に保存し直す必要があります。

アーカイブと

guard let archivedData = UserDefaults.standard.value(forKey: "myDict") as? Data 
     else{return} 
    guard let unarchivedDictionary = NSKeyedUnarchiver.unarchiveObject(with: archivedData) as? [String:String] 
     else{return} 
+0

投稿の編集を確認してください –

+0

私はuserdefaultsが遊び場でどのように処理されているのか分かりません。あなたは新しいプロジェクトでこれをやろうとして、結果を更新できますか? – ebby94

0

Userdefaultsは遊び場では動作しない辞書にデータを取得し、アーカイブしないUserDefaultsに

let myDict = [String:String]() 
    let data = NSKeyedArchiver.archivedData(withRootObject: myDict) 
    UserDefaults.standard.set(data, forKey: "myDict") 

を保存します。 Simulatorのアプリケーションで実装して起動する必要があります

関連する問題