Crypto Comare API response data type - json

I am making a call to Crypto Compares API to get all of the tickers along with their data (https://www.cryptocompare.com/api/data/coinlist/). I am having difficulty finding what the data type is of the returned json. I am able to turn it into a [String: Any], but the value looks like it also contains two dictionaries. Here is my code where I try to cast the json object into the dictionary.
guard let responseDictionary = responseObject as? [String: Any] else {
print("WRONG")
return
}
The code above successfully works, but I am not able to access the rest of the dictionary. I have also tried [String: [String: Any]] and most variations of it. Just for reference.. I am trying to access the coin name in the return.
***UPDATE: For anyone interested I had to save the responseDictionary["Data"] as! [String: [String: String]] then I could access the rest of the data as a dictionary, however when casting the responseObject it would only let me use [String: Any] instead of [String: [String: Any]]

In your case, since you are not sure about the format of the dictionary, use dump to print it out beautifully. Then you can figure out a propert way of casting using guard let
Try this out
dump(responseObject)

Related

Parse response of type AnyObject into Codable model

I have started on someone's project having difficulties in parsing the response into Codable model. Below is the code snippet, which returns me resultData as AnyObject
switch response.result {
case .success(let resultData):
taskCallback(1, resultData as AnyObject)
case .failure(let error):
print(error)
}
I have been trying to parse the response into Codable model but it requires me AnyObject of type Data. How do I convert AnyObject into type Data.
let model = try JSONDecoder().decode([SomeModel].self, from: resultData)
I can't alter the completion handler response as its being used at so many places
[Here is the screenshot of printed response of responseObject]
[1]: https://i.stack.imgur.com/g6RRM.png
JSON is almost certainly a wrapper around JSONSerialization (there is no stdlib or Foundation type called "JSON"). So if you want to turn that into Data, you would use JSONSerialization again. For example:
let data = try JSONSerialization.data(withJSONObject: resultData)
This is of course very inefficient (you're decoding the JSON, re-encoding it, and the decoding it a second time), but it may be a stop-gap measure as you refactor to get rid of the AnyObject and use Decodable for the initial decoding.

Swift - Convert [[String:Any?]] to Data

I have an [[String:Any]] object populated like:
var result : [[String : Any]] = [[String : Any]]()
And I need convert it to Data.
I'm just using:
JSONEncoder().encode(result)
To convert it.
But I get this error:
Generic parameter 'T' could not be inferred
Exist a simple way to convert a [[String:Any?]] object toData` ?
JSONEncoder can only encode objects whose type conforms to Encodable. If you want to encode Any to JSON, you need to use JSONSerialization to do that.
let jsonData = try? JSONSerialization.data(withJSONObject:result)
You can also using struct for that and using
let data = try? JSONEncoder().encode(struct_Object))

Data and Date casting in JSON serialized dictionary

I have some codable struct and I'd like to create a [String:Any] dictionary from it to iterate over its properties. I created a computed property:
var dictionary: [String: Any] {
return (try? JSONSerialization.jsonObject(with: JSONEncoder().encode(self), options: [])) as? [String: Any] ?? [:]
}
When I iterate over the dictionary and try to cast 'Any', types like 'Data' and 'Date' never work. Casting works only for 'String', 'Int' and 'Double'. Is it possible to cast the 'Data' and 'Date' somehow? Thank you in advance.
JSON has no predefined or standard encoding for dates or byte sequences (data).
Both JSONEncoder and JSONDecoder have properties dateEncodingStrategy and dataEncodingStrategy you can set to match whatever format you're using in your JSON.

Reading JSON output in Swift

I am trying to read a JSON output from a web app. This output is:
[{"group_name":"XYZ","adminof":0}]
I have a struct that looks like:
struct grouplistStruct{
var group_name : String
var adminof : Any
}
The code that I am using is:
let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as! [Any]
for jsonResult in jsonArray{
let loc = grouplistStruct(group_name: jsonResult["group_name"], adminof: jsonResult["adminof"])
I can see that jsonArray reads the value correctly. Similarly in the for loop, jsonResult is also reading the value correctly
But when I try to assign this value to a Struct variable, it shows an error:
Type 'Any' has no subscript members
Why is that happening? Sorry I am new to Swift so I am learning all this.
Since your json data is an array containing dictionaries like this:
[{"group_name":"XYZ","adminof":0}]
You are getting the error
Type 'Any' has no subscript members
because you are downcasting the json as an array of Any and in swift Any (as the name suggests) represents any type like Int, Double or Dictionary of type [String: String] as you know that Int or Double can not have subscript like someInt["subscript"]
So you need to downcast to this specific type using [[String: Any]] .
This represents an array containing the dictionaries of type [String: Any]. This will work because dictionaries can have subscript members e.g someDict["group_name"]
Hence you should use [[String: Any]] instead of [Any] in this statement try JSONSerialization.jsonObject(with: data, options: []) as! [Any]

having trouble drilling down into response json using alamofire. Swift

Ok so im having trouble drilling down into the response json that is retrieved in the below code.
Snapshot 1:
Snapshot 2:
I get the json above as a response, yet when I try to drill down into the json I cannot access the key "Address" or any other key that is held under bookings. it finds bookings but then assigns the variables i created for each key's value (address, state, zipcode, and city) and assigns these variables as null. My only theory is that the response json has "()" right after bookings instead of the normal "{}". Those brakets do appear after the parentheses, so how would i drill into that with out a key? I am still new to the app dev world so i could be completely wrong, just this request method has worked for me in the past when i've received "{}" after the first key.
1) You are using method valueForKeyPath() to get value from dictionary.
Change it to valueForKey().
2) Value for key "bookings" will give you array.
Try this code.
let data = JSON as! NSDictionary;
//value for key "bookings" will give you array
if let bookings = data.valueForKey("bookings") as? NSArray {
let bookingObj = bookings[0] as! NSDictionary;
self.address = bookingObj.valueForKey("address");
self.state = bookingObj.valueForKey("state");
self.zip = bookingObj.valueForKey("zip");
self.city = bookingObj.valueForKey("city");
}
FYI Please Note that, method valueForKeyPath() returns array of value for particular key from the array of dictionaries.
e.g. suppose you have multiple objects of bookings array, and you use
let arrayAddresses = bookings.valueForKeyPath("address") as! NSArray
this will return string array containing only address of all object.
Another point, '()' means Array Value, '{}' means Dictionary value.
I'd suggest using Swift types (like [String: AnyObject]) instead of Foundation types (like NSDictionary), and on top of that, you should print out when something fails so you know what's wrong. So starting from your let data = ... line, try this instead:
if let data = JSON as? [String: AnyObject],
bookings = data["bookings"] as? [[String: AnyObject]],
booking = bookings[0] {
self.address = booking["address"] as? String
self.state = booking["state"] as? String
self.zipCode = booking["zip"] as? String
self.city = booking["city"] as? String
print(self.address)
} else {
print("Couldn't parse booking from JSON")
}
More on why typing is important (and why you should use [[String: AnyObject]] instead of NSArray) in this article. You can be more specific and more concise if you use proper types.