Swift 4 декодирование / кодирование общей структуры данных

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

Я попытался согласовать очередь с кодируемыми и декодируемыми, кодировать данные и сохранять их в соответствии с пользовательскими настройками по умолчанию, но это, похоже, не работает, на самом деле моя функция init (из декодера) даже застряла в бесконечном цикле по какой-либо причине. Мне действительно нужна помощь

// Моя очередь

public struct Queue<T: Codable> {

    private var dataSource  = [T]()
    private var userDefaults = UserDefaults()
    public init() {}


    public func isEmpty() -> Bool{

        return  dataSource.isEmpty
    }

    public mutating func enqueue( element: T){
        dataSource.append(element)
   }

   public mutating func dequeue() -> T?{
        return isEmpty() ? nil : dataSource.removeFirst()
    }

    public func peek() -> T? {
        return isEmpty() ? nil : dataSource.first
    }

    public func getCount() -> Int {
        return dataSource.count
    }

    public func printQueue(){
        print(dataSource)
    }
}





public enum Error: String, Swift.Error{
    case queueNotFound = "Queue Not Found!"
}

extension Queue: Encodable, Decodable {
    public func encode(to encoder: Encoder) throws
    {
        let jsonEncoder = JSONEncoder()
        let encodedData = try  jsonEncoder.encode(dataSource)
        userDefaults.set(encodedData, forKey: "queue")
        print(encodedData)
        //var container = encoder.container(keyedBy: CodingKey.self)
    }

    public init(from decoder: Decoder) throws
    {
     print("intilaizing")
        let jsonDecoder = JSONDecoder()
        guard let data = userDefaults.data(forKey: "queue"), let _ =         try? jsonDecoder.decode(Queue.self, from: data)
            else {
                throw Error.queueNotFound
        }

    }

Любой класс должен иметь возможность добавить эту очередь в качестве члена данных, когда я реализую очередь, функция кодирования работает, как я полагаю, но декодер вызывает некоторый бесконечный цикл


person Michaud Reyna    schedule 25.05.2019    source источник
comment
по какой причине я не должен использовать кодировку?   -  person Michaud Reyna    schedule 26.05.2019


Ответы (2)


Вы кодируете dataSource - это [T] - но декодируете Queue, это не может работать. Пытаться

public init(from decoder: Decoder) throws
{
    print("initializing")
    guard let data = userDefaults.data(forKey: "queue") else { throw Error.queueNotFound }
    dataSource = try JSONDecoder().decode([T].self, from: data)
}

Кстати, в вашем коде декодированное значение - а также потенциальное DecodingError - не используется, что не имеет смысла.

person vadian    schedule 25.05.2019

extension Queue {
  enum CodingKeys: String, CodingKey {
          case dataSource
 }


extension Queue: Encodable, Decodable {

public func encode(to encoder: Encoder) throws
{
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(dataSource, forKey: .dataSource)
}

public init(from decoder: Decoder) throws
{
    print("initializing Queue:")
    let data = try decoder.container(keyedBy: CodingKeys.self)
    dataSource = try data.decode(Array.self, forKey: .dataSource)
}

Вместо этого я переключился на использование CodingKeys и изменил тип на Array.self (Array), который по сути является того же типа, что и переменная dataSource ([T])

person Michaud Reyna    schedule 07.01.2020