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))
Related
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.
Does Swift provide a way to convert a raw String like this
"[\"John\",\"Anna\",\"Tom\"]"
to an Array of strings ([String])?
I've looked for a way to do it over StackOverflow, but in that specific way, I could not find an answer :/
On Swift 4 and later, use JSONDecoder:
let rawString = "[\"John\",\"Anna\",\"Tom\"]"
let jsonData = rawString.data(using: .utf8)!
let strings = try JSONDecoder().decode([String].self, from: jsonData)
Code Different answer is probably a recommended way to do it nowadays (Swift 4+).
For reference, here is a classic way to do the same, compatible with older Swift versions:
let rawString = "[\"John\",\"Anna\",\"Tom\"]"
let jsonData = rawString.data(using: .utf8)!
let strings = (try? JSONSerialization.jsonObject(with: jsonData, options: [])) as? [String] ?? []
According to Itai Ferber, JSONDecoder uses JSONSerialization under the hood, so it should do pretty much the same as Code Different answer.
I'm working on JSON serialization like below code:
let jsonData: Data? = try? JSONSerialization.data(withJSONObject: abc, options: .prettyPrinted)
let parsedDict = String(data: jsonData!, encoding: String.Encoding.utf8)
print(" parse Dict Value \(parsedDict!)")
abc data is:
{
"ActedTime" = "2017-09-19 12:04:12",
"EventDate" = "2017-10-06 07:03:29"
}
After completion of serialization, the response value is:
"{\n \"ActedTime\" : \"2017-09-19 12:04:12\",\n \"EventDate\" : \"2017-10-06 07:03:29\”}”
I printed the parsedDict like below:
{
"ActedTime" : "2017-09-19 12:04:12",
"EventDate" : "2017-10-06 07:03:29"
}
The stored data seems like string format, but data is printed like dictionary.
How can I get dictionary format for sent the parameters to another API like dictionary format.
Please help me,
Thanks in Advance.
Omit .prettyPrinted, the server doesn't care anyway.
let jsonData = try? JSONSerialization.data(withJSONObject: abc)
And if the object is supposed to be a dictionary, why do you serialize it at all?
However if the data is supposed to be passed in a POST request as httpBody pass jsonData rather than parsedDict.
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]
After reading up a bit on collections, I began to wonder if json deserialization was going to be an issue given that collections need to specify a type for the values they contain. And in the case of dictionaries, one would need to specify the type for both the key and the value.
After a bit of experimentation, I found that the following works:
let jsonString = "{\"bool\": true, \"num\": 1,\"string\": \"a string\"}"
let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let json : AnyObject! = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil)
let valid = NSJSONSerialization.isValidJSONObject(json)
And when I use a playground (or am in the REPL), I get the following when printing out the contents of the json object:
["num": 1, "string": "a string", "bool": 1]
My question: is there may be a better way to handle this?
I'd suggest typing your json object a little more:
let json = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as? Dictionary<String, AnyObject?>
This will help you access elements by their key.