Convert value of type 'Dictionary<String, JSON>' to expected argument type 'Data'

Hello everyone,

I am a beginner to Swift and Programming so please do forgive me if this a rather obvious question/answer.
Im trying to work with JSON and I have very little experience doing so, to make it easier on myself I figured I would use the Almofire and SwiftyJSON packages.
So far I've been able to successfully print out the JSON response, but mapping it to a struct has been rather challenging.
The current error I get is convert value of type 'Dictionary<String, JSON>' to expected argument type 'Data'

This is my struct

**struct** LitecoinDictionary: Decodable{
**var** lastBlock: Int
**var** lasDayBlock: Int
**var** workers: Int
**var** port: Int
**var** shares: Int
**var** enabled: Bool
**var** height: Int
**var** name: String
**var** abbreviation: String
**var** algo: String
**var** timesincelast: Int
**var** hashrate: Double
**var** lastDayBTC: Double
}

And this is my code for the request.

let statusRequest = AF.request(specificCurrencies, method: .get).validate().responseJSON { response in
    switch response.result {
    case .success(let value):
        let json = JSON(value)
        print("JSON: \(json)")
        let endResponse: Dictionary<String, JSON> = json["data"].dictionaryValue
        print(endResponse)
        print(endResponse["port"] as Any)
        do {
          let jsonDecoder = JSONDecoder()
          let decodedResponse = try jsonDecoder.decode(LitecoinDictionary.self,
                                                       from: endResponse)

          print(decodedResponse)
        } catch {
          print(error)
        }
        case .failure(let error):
        print(error)
    }
}

You shouldn't use responseJSON, you should use responseDecodable and provide your LitecoinDictionary type. That way Alamofire takes care of the decoding for you. You can also dump the SwiftyJSON dependency at that point.

.responseDecodable(of: LitecoinDictionary.self) { response in 

}
1 Like

Thanks for the response Jon_Shier!
I swapped out all the bulk of the code for responseDecodable as you suggested.

re-running it I get an expected to decode Array<Any> but found a dictionary instead error. Im guessing this is because my model wasn't correctly setup to the actual JSON response. I tried cleaning it up and having it more matching but maybe I'm completely missing something?

the actual JSON output

{
    "code": 200,
    "status": "success",
    "data": {
        "algo": "scrypt",
        "port": 3333,
        "name": "Litecoin",
        "abbreviation": "LTC",
        "enabled": true,
        "height": 2123394,
        "workers": 6577,
        "shares": 0,
        "hashrate": 2.8479085151607686E12,
        "24h_blocks": 3,
        "24h_btc": 0.1456939553773598,
        "lastblock": 2123255,
        "timesincelast": 23644
    }
}

my new model

**struct** LTCStruct: Decodable{
**var** code: Int
**var** status: String
**var** data: [DataStruct]
}

**struct** DataStruct: Decodable {
**var** algo: String
**var** port: Int
**var** name: String
**var** abbreviation: String
**var** height: Int
**var** shares: Int
**var** hashrate: Double
**var** lasDayBlock: Int
**var** lastDayBTC: Double
**var** lastBlock: Int
**var** timesincelast: Int
// dont know if needed
**var** workers: Int?
**var** enabled: Bool?
}

As the error states, your data value is a dictionary in the JSON, not an array. It should have the type DataStruct, not [DataStruct]. I suggest you review the documentation for the API you're hitting so you can see what kind of structure guarantees they may for the data value.

1 Like

That makes sense, as I had submitted my reply I had thought "its probably that im using the wrong data type somewhere" but I would have still been wrong as my mind went towards trying to make DataStruct into an array.
Removing the [] around DataStruct made everything print out!
Now on to figuring out how to access said data haha!

Terms of Service

Privacy Policy

Cookie Policy