-2

I'm trying to receive data from a JSON link in Swift Playground on Mac, I've struct all the data, but I'm having issue trying to decode all of the data, receiving the error: "Referencing instance method 'decode(_:from:)' on 'Array' requires that 'Bicimia' conform to 'Decodable'"

I've already tries to add the Codable/Decodable option, and tried to change the URLSession respectively, but nothing has changed.

struct Bicimia {

    let network: Network

}


struct Network {

    let company: [String]
    let href, id: String
    let location: Location
    let name: String
    let stations: [Station]

}

struct Location {

    let city, country: String
    let latitude, longitude: Double

}

struct Station {

    let emptySlots: Int
    let extra: Extra
    let freeBikes: Int
    let id: String
    let latitude, longitude: Double
    let name, timestamp: String

}

struct Extra {

    let extraDescription: String
    let status: Status

}

enum Status {

    case online
}


let url = "https://api.citybik.es/v2/networks/bicimia"
let urlOBJ = URL(string: url)

URLSession.shared.dataTask(with: urlOBJ!) {(data, response, error) in


    do {
        let res = try JSONDecoder().decode([Bicimia].self, from: data!)
        print(res)
    }
    catch {
        print(error)
    }
}.resume()
vadian
  • 274,689
  • 30
  • 353
  • 361

1 Answers1

1

To be Decodable all properties should be Decodable down the chain:

struct Bicimia: Decodable {
    let network: Network // should be decodable
}

struct Network: Decodable {
    let company: [String]
    let href, id: String
    let location: Location // should be decodable
    let name: String
    let stations: [Station] // should be decodable
}

struct Location: Decodable {
    let city, country: String
    let latitude, longitude: Double
}

struct Station: Decodable {
    let emptySlots: Int
    let extra: Extra // should be decodable
    let freeBikes: Int
    let id: String
    let latitude, longitude: Double
    let name, timestamp: String
}

struct Extra: Decodable {
    let extraDescription: String
    let status: Status // should be decodable
}

enum Status: String, Decodable {
    case online
}

Note that enums can not be Decodable alone, because they should know what is the raw value, or you should manually decode them in decode function.

Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
  • That worked without problem, but now in the terminal I receive an error saying: "typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))" – Giovanni Filippini Oct 05 '19 at 20:07
  • 1
    use `let res = try JSONDecoder().decode(Bicimia.self, from: data!)` instead of [Bicimia.self]... – Stephan Schlecht Oct 05 '19 at 20:09
  • That is another issue, but you should decode as @StephanSchlecht mentioned. Please do not ask another question in the comment. Except, feel free [to ask a new one](https://stackoverflow.com/questions/ask) if you need to. And don't forget to **mark as answer** if this was the answer to the original question as you said. – Mojtaba Hosseini Oct 05 '19 at 20:22