0

I am trying to parse JSON data over the network. Below you can see where the magic is happening.

func getBookingsForDate(date: String, completionHandler: @escaping ([String:String]) -> Void ){

struct bookings: Codable {

    var bookieName : String
    var bookieNumber: String
    var booked: String
    var bookingTime: String

    private enum Codingkeys: String, CodingKey{

        case bookieName
        case bookieNumber
        case booked
        case bookingTime
    }
}

let params = ["date":date]

let urlString = "http://mscissorss.pythonanywhere.com/getBookings/"
Alamofire.request(urlString, method: .get, parameters: params).responseJSON {
    response in
    switch response.result {
    case .success(let JSON):

        let decoder = JSONDecoder()
        guard let _ = response.data else{
            return
        }
        do {
            let loginDetails = try decoder.decode(bookings.self, from: response.data!)
            print(loginDetails)
        } catch let err{
            print(err)
        }

        //let bookings = JSON as! NSDictionary
        //completionHandler(JSON)
        /*
        do {
            let decoder = JSONDecoder()
            let gitData = try decoder.decode(bookings.self, from: JSON)
            print(gitData.bookieName)

        } catch let err {
            print("Err", err)
        }
        */
        break
    case .failure(let error):
        print(error)
    }
}
}

Given the code i am getting the following error message:

keyNotFound(CodingKeys(stringValue: "bookieName", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"bookieName\", intValue: nil) (\"bookieName\").", underlyingError: nil))

And the JSON response that i am getting looks like this:

{
    0 =     {
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "10:00";
    };
    1 =     {
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "10:30";
    };
    10 =     {
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "15:00";
    };
    11 =     {
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "15:30";
    };
    12 =     {
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "16:00";
    };
    13 =     {
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "16:30";
    };
    14 =     {
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "17:00";
    };
    15 =     {
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "17:30";
    };
    16 =     {
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "18:00";
    };
    2 =     {
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "11:00";
    };
}

It is the first time i am decoding so if you have an answer please try to explain a bit to why i need to make the change that i need.

UPDATE

After changing the code to what @sh_khan and @vadian suggested it worked to parse it however i am still getting this error inside my parsed object:

["1": MagicS.(unknown context at 0x106932738).bookings(bookieName: "", bookieNumber: "", booked: "false", bookingTime: "10:30"), 
"0": MagicS.(unknown context at 0x106932738).bookings(bookieName: "", bookieNumber: "", booked: "false", bookingTime: "10:00"),

Also, if i want to be able to access a single value lets say the first item with the key "0" -> bookieName, how would i do that using loginDetails

1
  • 1
    You aren't managing the first level with is the "11" key (for instance, or all the other ones in fact). What you can decode with your current code is something like that: {"booked":false,"bookieName":"","bookieNumber":"","bookingTime":"10:00"}. Commented Nov 19, 2018 at 15:03

2 Answers 2

3

Firs booked is a Bool and no need for private enum Codingkeys if you won't rename the keys

struct Booking: Codable {

   let bookieName : String
   let bookieNumber: String
   let booked: Bool
   let bookingTime: String

}

Second decode like this

let loginDetails = try decoder.decode([String:Booking].self, from: response.data!)
Sign up to request clarification or add additional context in comments.

3 Comments

The parse is successful context is where you write the class in
I did not understand what you mean. Could you explain in another way? @sh_Khan
your context is the projectName.className
0

The root object is a dictionary with String keys and Bookings values – please name structs with a starting capital letter.

So you have to decode

let loginDetails = try decoder.decode([String:Bookings].self, from: response.data!)

2 Comments

The unknown context is not related to the question about keyNotFound(CodingKeys. And what is MagicS? To get the value for a specific key just write loginDetails["0"]!.bookieName
MagicS is the name of my swift project.Thank you for answering the other question @vadian

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.