0

I'm making an api request:

var urlRaw = bookSummaryReadsDomainUrl + apiKey;
let url = URL(string: urlRaw.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)

let task = URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in
    if let error = error {
        print("Error with fetching book summary reads: \(error)")
        return
    }
    
    guard let httpResponse = response as? HTTPURLResponse,
        (200...299).contains(httpResponse.statusCode) else {
            print("Error with the response, unexpected status code: \(response)")
            return
    }
    if let data = data,
        let flurryItems = try? JSONDecoder().decode(FlurrySummary.self, from: data) {
        completionHandler(flurryItems.rows ?? [])
    }
})
task.resume()

to an endpoint that returns the following data

{
"rows": [
{
"dateTime": "2020-07-04 00:00:00.000-07:00",
"event|name": "BookSummaryRead",
"paramName|name": "bookId",
"paramValue|name": "elon-musk",
"count": 12
},

... ]

import Foundation

struct FlurrySummary: Codable {
    var rows: [FlurryItem]?
    enum CodingKeys: String, CodingKey {
        case rows = "rows"
    }
}


struct FlurryItem: Codable {
    var name: String?
    var event: String?
    var value: String?
    var count: String?
    var date: String?
    enum CodingKeys: String, CodingKey {
        case name = "paramName|name"
        case event = "event|name"
        case value = "paramValue|name"
        case count = "count"
        case date = "dateTime"
    }
}

For some reason the JSONDecoder.decode part is not working. It's not filling up the flurryItems and flurryItems.rows = nil. What am I doing wrong?

4
  • catch the error and print it Commented Jul 5, 2020 at 15:24
  • How do you expect to figure out the error ignoring it? Commented Jul 5, 2020 at 15:24
  • 1
    I’d suggest not using try? with the decode, because that discards any diagnostic error, if it failed. Use do-try-catch and see what error you get. Commented Jul 5, 2020 at 15:24
  • Btw you are abusing of the optionals. You should declare optional only the properties that might be nil not every property. You should declare your properties as constants. Commented Jul 5, 2020 at 15:26

1 Answer 1

1

The property count in FlurryItem has to be of type Int.

var count: Int?

You have to catch the Error that are thrown.

do {
    if let data = data,
        let flurryItems = try JSONDecoder().decode(FlurrySummary.self, from: data) {
        completionHandler(flurryItems.rows ?? [])
    }
} catch { print(error) }

Also, you don't need the CodingKeys in FlurrySummary since the property name is the same.

struct FlurrySummary: Codable {
    var rows: [FlurryItem]?
}

Note: Also, avoid using optional declaration if the property never becomes null.

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

3 Comments

This will fix the error but code only answers are not helpful for future readers.
Btw does it need to be optional? Does it need to be a variable instead of a constant?
Are the Coding keys necessary for the root structure?

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.