0

I have a generic Queue data structure which utilizes an array as its list, I am having hard time making the queue conform to encodable and decodable. I have another class which uses the queue which also needs to be Codable but it cannot be coddle unless its member variables are.

I have tried conforming the queue to encodable and decodable, encoding the data and saving it to user defaults but this does not seem to be working, in fact my init(from decoder) function is even stuck in an infinite loop for whatever reason. I could really use some assistance

//My Queue

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
        }

    }

Any class should be able to addd this queue as a data member, when I implement the queue the encode function works I believe but the decoder causes some infinite loop

2 Answers2

1

You are encoding dataSource – which is [T] – but are decoding Queue, this cannot work. Try

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)
}

By the way in your code the decoded value – as well as a potential DecodingError – is unused which makes no sense.

vadian
  • 274,689
  • 30
  • 353
  • 361
0
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)
}

I switched over to using CodingKeys instead, and changed the type to Array.self (Array) which essentially is the same type as the dataSource variable ([T])