JsonEncoder всегда возвращает пустой массив - PullRequest
1 голос
/ 15 марта 2019

Я пытаюсь сохранить массив массива в UserDefaults, и я не могу понять, почему JsonEncoder возвращает пустые данные.У меня есть модель установки, которая соответствует протоколу Codable

struct MenuItem : Codable{
    let name : String?
    let icon : String?

    init(name : String?, icon : String?){
        self.name = name
        self.icon = icon
    }
}

, а также создал менеджер по умолчанию для сохранения его в пользовательские настройки по умолчанию.

class DefaultsManager {

    static let shared = DefaultsManager()

    init(){}

    var items: [MenuItem]{
        get{
            if let json = UserDefaults.standard.data(forKey: "key"){
                return decodeFromJson(jsonData: json)
            } else {
                return []
            }
        }
        set{
            let json = codeToJson(data: items)
            UserDefaults.standard.set(json, forKey: "key")
        }
    }

    fileprivate func codeToJson<T:Codable>(data: Array<T>) -> Data?{
        do {
            return try JSONEncoder().encode(data)
        } catch {
            print(error)
            return nil
        }
    }

    fileprivate func decodeFromJson<T:Codable>(jsonData: Data) -> [T]{
        do {
            return try JSONDecoder().decode(Array<T>.self, from: jsonData)
        } catch {
            print(error)
            return []
        }
    }
}

но что бы я ни делал, JsonEncoder возвращает пустые данные .. Я пытался гуглить, но безуспешно.

Ответы [ 2 ]

1 голос
/ 15 марта 2019

Это очень распространенная ошибка.

В установщике вычисляемого свойства новое значение представляется неявной переменной newValue, это не само свойство.

set {
   let json = codeToJson(data: newValue)
   UserDefaults.standard.set(json, forKey: "key")
}
0 голосов
/ 15 марта 2019

Изменить Array<T>.self на [MenuItem].self

   return try JSONDecoder().decode([MenuItem].self, from: jsonData)
...