Data and Date casting in JSON serialized dictionary - json

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.

Related

Convert NSObject to JSON string

I have a class that conforms to NSObject and has fields like NSNumber and NSMutableArray, so cannot really use Codable here.
So the class is like this:
class Custom: NSObject {
var users: NSMutableArray?
var type: NSNumber?
.. and many more fields
}
Now i have an object of this class and want to get JSON string from that object :
I have tried following :
let json = try? JSONSerialization.data(withJSONObject: customObject, options: JSONSerialization.WritingOptions.prettyPrinted) as? [String: Any]
let json = try? JSONSerialization.data(withJSONObject: paymentData, options: JSONSerialization.WritingOptions.prettyPrinted)
The above two code gave crash like Invalid top-level type in JSON write'
And used SwiftyJson library too but that too gave the error SwiftyJSON.SwiftyJSONError.unsupportedType
I wanted to try Codable but that requires me to convert NSNumber to Int and MSMutableArray to Array but I cannot really change this as I have used this code in many other places and also my code is working with Objective C so either I had to use NSNumber or had to convert between Int and NSNumber too many times.
Is there a solution that doesn't require changing the current implementation of class and still convert the object to json.
Any help would be appreciated.

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))

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]

Crypto Comare API response data type

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)

How do you create a SwiftyJSON dictionary out of optional AnyObjects?

I recently ran into a very time-consuming issue for a simple task of creating a JSON dictionary with optional objects. I'm using SwiftyJSON.
If I create the following dictionary, I get thrown errors
JSON type doesn't have an initializer that supports Dictionary<String,AnyObject?>
But if I simply change AnyObject to an non-optional type, it works.
var dict: Dictionary <String, AnyObject?> = [
"title" : title as? AnyObject,
"date" : date as? AnyObject,
]
var jsonData: JSON = JSON(dict) // this is where I get the error
I need to actually a JSON data set that potentially has nil values, but it seems like SwiftyJSON doesn't allow it.
Is there any way I can create a JSON dictionary with optional objects using SwiftyJSON?
Neither any key nor any value of a Swift Dictionary can be nil.
You could declare the variable as optional
var dict: Dictionary <String, AnyObject>?