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

1
  • what is the reason I should not use encode? Commented May 26, 2019 at 20:13

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.