Swift: как сохранить и загрузить словарь со значениями структуры в Userdefaults - PullRequest
0 голосов
/ 23 сентября 2019

Я прочитал несколько сообщений на эту тему в StackOverflow.Насколько я понял, я не могу сразу сохранить каждый объект в Swift в userdefaults.На первом этапе я попытался преобразовать свой словарь в объект NSData, но уже на этом этапе у меня ничего не получилось.Что я делаю неправильно?Спасибо за вашу помощь!

Я хочу управлять настройками приложения в упомянутом словаре.Словарь со значением struct был бы лучшим решением для меня.

import Foundation
import UIKit


struct Properties: Codable {
    var v1: String
    var v2: Int
    var v3: Bool
}


let userdefaults = UserDefaults.standard

var dictStruct: Dictionary<String, Properties> = [:]

dictStruct["a"] = Properties(v1: "AAA", v2: 0, v3: false)
dictStruct["b"] = Properties(v1: "BBB", v2: 1, v3: true)


let dataEncoded: Data = try NSKeyedArchiver.archivedData(withRootObject: dictStruct, requiringSecureCoding: false)

userdefaults.set(dataEncoded, forKey: "KeyData")

let dataDecoded = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(userdefaults.object(forKey: "KeyData") as! Data) as! Dictionary<String, Properties>

print(dataDecoded["a"]!.v1)

Выполнение игровой площадки прекращено: произошла ошибка, и она не была обнаружена: Ошибка Domain = NSCocoaErrorDomain Code = 4866 "Caughtисключение во время архивирования: - [__ SwiftValue encodeWithCoder:]: нераспознанный селектор, отправленный экземпляру 0x600000fc73c0 ...

1 Ответ

0 голосов
/ 23 сентября 2019

Вы смешиваете Codable и NSCoding.NSKeyed(Un)Archiver принадлежит NSCoding.Не используйте его.

Правильный API для Codable: PropertyListEncoder/-Decoder

struct Properties: Codable {
    var v1: String
    var v2: Int
    var v3: Bool
}

let userdefaults = UserDefaults.standard

var dictStruct: Dictionary<String, Properties> = [:]

dictStruct["a"] = Properties(v1: "AAA", v2: 0, v3: false)
dictStruct["b"] = Properties(v1: "BBB", v2: 1, v3: true)

do {
    let dataEncoded = try PropertyListEncoder().encode(dictStruct)

    userdefaults.set(dataEncoded, forKey: "KeyData")

    if let data = userdefaults.data(forKey: "KeyData") {
       let dataDecoded = try PropertyListDecoder().decode([String:Properties].self, from: data)
       print(dataDecoded["a"]!.v1)
    }
} catch { print(error) }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...