Cannot convert Data to NSDictionary - json

I'm trying to convert data from URLSession to a NSDictionary but it fails when converting the data to dictionary.
Following:
let json = try? JSONSerialization.jsonObject(with: data!, options: [])
print(json ?? "NotWorking")
outputs
(
{
babyId = 1;
id = 17;
timestamp = "2018-06-30 09:23:27";
}
)
But when I try to convert it into a Dictionary with following it outputs nil.
let json = try? JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
The webpage outputs
[{"id":"17","babyId":"1","timestamp":"2018-06-30 09:23:27"}]
Where does the error occurs?

[ ] means array in JSON. { } means dictionary. You have an array of dictionary. Note that when you print an array in Swift, you will see ( ).
Don't use NSArray or NSDictionary in Swift without a very clearly understood and specific reason. Use a Swift array and dictionary of the proper types.
Your code should be:
do {
if let results = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]] {
// results is now an array of dictionary, access what you need
} else {
print("JSON was not the expected array of dictonary")
}
} catch {
print("Can't process JSON: \(error)")
}
And really you shouldn't be using data! either. Somewhere above this you should have a if let data = data {

Related

Swift MacOS getting bad json response from jsonSerialization

I am trying to convert a string to JSON in Swift.
Here's the string, which I am getting by pulling the innerHTML from a WKWebView.
{"list":{"pagination":{"count":3,"hasMoreItems":false,"totalItems":3,"skipCount":0,"maxItems":100},"entries":[{"entry":{"createdAt":"2020-06-16T21:00:32.714+0000","isFolder":false,"isFile":true,"createdByUser":{"id":"UserFName.userLName#xxxxxxxx.com","displayName":"UserFName userLName"},"modifiedAt":"2020-06-16T21:00:32.714+0000","modifiedByUser":{"id":"UserFName.userLName#xxxxxxxx.com","displayName":"UserFName userLName"},"naxxxxxxxxme":"00-invest-2020-06-16-17-00-32-716.txt","id":"028b4c82-09b8-4ee5-b4fa-9696a33b026d","nodeType":"log:fileNode","content":{"mimeType":"text/plain","mimeTypeName":"Plain Text","sizeInBytes":609373,"encoding":"UTF-8"},"parentId":"ba647bfc-a889-4d91-9211-4220cfe7d90a"}},{"entry":{"createdAt":"2020-06-16T21:01:12.828+0000","isFolder":false,"isFile":true,"createdByUser":{"id":"UserFName.userLName#xxxxxxxx.com","displayName":"UserFName userLName"},"modifiedAt":"2020-06-16T21:01:12.828+0000","modifiedByUser":{"id":"UserFName.userLName#xxxxxxxx.com","displayName":"UserFName userLName"},"name":"00-monetize-2020-06-16-17-01-12-830.txt","id":"d6412e3a-fea5-4d4d-a962-d91cde294bc9","nodeType":"log:fileNode","content":{"mimeType":"text/plain","mimeTypeName":"Plain Text","sizeInBytes":996653,"encoding":"UTF-8"},"parentId":"ba647bfc-a889-4d91-9211-4220cfe7d90a"}},{"entry":{"createdAt":"2020-06-16T18:33:49.344+0000","isFolder":true,"isFile":false,"createdByUser":{"id":"UserFName.userLName#xxxxxxxx.com","displayName":"UserFName userLName"},"modifiedAt":"2020-06-16T18:34:49.211+0000","modifiedByUser":{"id":"UserFName.userLName#xxxxxxxx.com","displayName":"UserFName userLName"},"name":"20200616","id":"d881db96-ddcb-44ae-99e1-ffe3ac0c2810","nodeType":"cm:folder","parentId":"2fcf4c49-be4c-4f2c-a90b-654ae092c63e"}}]}}
I've checked the string in JSON Lint and it says it is valid.
Here's what I am doing in my code to convert it:
let strJSONLiteral = """
\(strJSON)
"""
//convert string to json
let data = strJSONLiteral.data(using: .utf8)!
do {
if let myJSON = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [Dictionary<String,Any>]
{
print(myJSON) // use the json here
} else {
print("bad json")
}
} catch let error as NSError {
print(error.localizedDescription)
}
The error is occurring in the JSONSerialization attempt. I'm getting nil for myJSON. Data check looked ok, has 1600+ bytes.
The top-level JSON is of type Dictionary while you're trying to decode an Array of Dictionary. To fix this
Replace:
if let myJSON = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [Dictionary<String,Any>]
With:
if let myJSON = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? Dictionary<String,Any>
Or you can just use [String: Any].
Add-on: You should probably do a bit of research on Codable and try to use it for these scenarios.

JSON String to Dictionary in Swift 4

I'm getting response from server in JSON in this format.
{"ResponseCode":1,"StudentDetails":[{"Student_ID":1,"Student_SchoolID":1,"Student_BranchID":1,"Student_ClassID":1,"Student_FirstName":"1","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"19/03/2017","Student_EnrollmentNo":"1","Class_Name":"1 QA","Student_Password":"123456","Student_PrimaryEmailID":"","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":true,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/student/compress/IMG100710620180809104233860.JPG","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0},{"Student_ID":278324,"Student_SchoolID":1404,"Student_BranchID":1408,"Student_ClassID":14193,"Student_FirstName":"Ganu now","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"01/01/0001","Student_EnrollmentNo":"","Class_Name":"1 QA","Student_Password":"123456","Student_PrimaryEmailID":"","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":false,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0},{"Student_ID":267971,"Student_SchoolID":1404,"Student_BranchID":1408,"Student_ClassID":4894,"Student_FirstName":"Poonam Dillo saii","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"01/01/0001","Student_EnrollmentNo":"2211","Class_Name":"Nursery A","Student_Password":"123456","Student_PrimaryEmailID":"","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":true,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/student/compress/FB_IMG_145451330612110622062018203844.jpg","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0},{"Student_ID":272466,"Student_SchoolID":1404,"Student_BranchID":1408,"Student_ClassID":14193,"Student_FirstName":"Poonam ganu","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"01/01/0001","Student_EnrollmentNo":"","Class_Name":"1 QA","Student_Password":"123456","Student_PrimaryEmailID":"","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":false,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0},{"Student_ID":273560,"Student_SchoolID":1404,"Student_BranchID":1408,"Student_ClassID":14564,"Student_FirstName":"Ganesh kumar saini","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"01/01/0001","Student_EnrollmentNo":"","Class_Name":"Primary","Student_Password":"123456","Student_PrimaryEmailID":"","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":false,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0},{"Student_ID":133262,"Student_SchoolID":1404,"Student_BranchID":1408,"Student_ClassID":5065,"Student_FirstName":"Lavish saini","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"04/02/2018","Student_EnrollmentNo":"09EEBMIT29","Class_Name":"KG ICA","Student_Password":"123456","Student_PrimaryEmailID":"ganeshsaini01#gmail.com","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":true,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/student/compress/download110682201811024710015409877121411061541069294120.jpg","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0}],"StudentMenusCount":[{"CountValue":0,"StudentId":0,"CountFor":"StudyPlanner","DatabaseID":0,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0}]}
Now this I'm getting in JSON String format. I need to convert it to Dictionary. I'm using this code to parse json.
let myJson = try JSONSerialization.jsonObject(with: response.data!, options: JSONSerialization.ReadingOptions.allowFragments) as Any
if myJson is String {
print(myJson) // Printing Here as myJson is String.
}
If I'm writing in above code as:
let myJson = try JSONSerialization.jsonObject(with: response.data!, options: JSONSerialization.ReadingOptions.allowFragments) as! [String: Any]
It's complaining about bad json than. Any idea of how to convert json string to Dictionary here?
This is the way to do it but you should say what is the error:
if let data = Data(result.utf8) {
do {
let myJson = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as! [String: Any]
} catch let error {
print(error)
}
}
I think the JSON is fine, however the way you parse JSON is not.
I tried with this code and the result is expected.
let response = """
{"ResponseCode":1,"StudentDetails":[{"Student_ID":1,"Student_SchoolID":1,"Student_BranchID":1,"Student_ClassID":1,"Student_FirstName":"1","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"19/03/2017","Student_EnrollmentNo":"1","Class_Name":"1 QA","Student_Password":"123456","Student_PrimaryEmailID":"","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":true,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/student/compress/IMG100710620180809104233860.JPG","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0},{"Student_ID":278324,"Student_SchoolID":1404,"Student_BranchID":1408,"Student_ClassID":14193,"Student_FirstName":"Ganu now","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"01/01/0001","Student_EnrollmentNo":"","Class_Name":"1 QA","Student_Password":"123456","Student_PrimaryEmailID":"","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":false,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0},{"Student_ID":267971,"Student_SchoolID":1404,"Student_BranchID":1408,"Student_ClassID":4894,"Student_FirstName":"Poonam Dillo saii","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"01/01/0001","Student_EnrollmentNo":"2211","Class_Name":"Nursery A","Student_Password":"123456","Student_PrimaryEmailID":"","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":true,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/student/compress/FB_IMG_145451330612110622062018203844.jpg","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0},{"Student_ID":272466,"Student_SchoolID":1404,"Student_BranchID":1408,"Student_ClassID":14193,"Student_FirstName":"Poonam ganu","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"01/01/0001","Student_EnrollmentNo":"","Class_Name":"1 QA","Student_Password":"123456","Student_PrimaryEmailID":"","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":false,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0},{"Student_ID":273560,"Student_SchoolID":1404,"Student_BranchID":1408,"Student_ClassID":14564,"Student_FirstName":"Ganesh kumar saini","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"01/01/0001","Student_EnrollmentNo":"","Class_Name":"Primary","Student_Password":"123456","Student_PrimaryEmailID":"","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":false,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0},{"Student_ID":133262,"Student_SchoolID":1404,"Student_BranchID":1408,"Student_ClassID":5065,"Student_FirstName":"Lavish saini","Student_MiddleName":"","Student_LastName":"","Student_Gender":"Male","Student_DOB":"04/02/2018","Student_EnrollmentNo":"09EEBMIT29","Class_Name":"KG ICA","Student_Password":"123456","Student_PrimaryEmailID":"ganeshsaini01#gmail.com","SchoolLogo":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/branch/compress/images106472017105803.jpg","Student_IsProfileImageUpload":true,"Student_IsSoftDelete":false,"Student_IsActive":true,"Branch_Name":"1","ProfilePicture":"https://s3-us-west-2.amazonaws.com/1/uploadeddocs/student/compress/download110682201811024710015409877121411061541069294120.jpg","DatabaseID":106,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0}],"StudentMenusCount":[{"CountValue":0,"StudentId":0,"CountFor":"StudyPlanner","DatabaseID":0,"IsSMSDisabled":false,"SMSBalance":null,"SMSSettingID":0,"NotificationSettingID":0,"IsSuperAdminUser":false,"SelectedSessionMasterID":0,"TargetedDate":null,"SelectedSessionType":0}]}
"""
if let data = response.data(using: .utf8) {
let myJson = try JSONSerialization.jsonObject(with: data,
options: JSONSerialization.ReadingOptions.allowFragments) as Any
if myJson is String {
print(myJson) // <-- This will not print anything as myJson is not a string
}
if let dict = myJson as? [String: Any] {
print(dict.keys) // <-- This will print a list of keys
}
}

Can not parse nested dictionary

I want to parse this JSON data, but I can't make it.
JSON data is like
My code is:
session.dataTask(with: request, completionHandler:{( data , response , error) -> Void in
if let data = data {
if let jsonObj = try? JSONSerialization.jsonObject(with: data , options: .allowFragments) as! Any {
print(jsonObj)
if let postdata = (jsonObj as AnyObject).value(forKey: "postdata") {
print(postdata)
//if let something = postdata["best_before"] as? NSDictionary{
// print(something)
The root object is clearly a dictionary ([String:Any]) not just something (Any) and use proper error handling and optional bindings to unwrap the optionals safely.
The value for key postdata is an array of dictionaries ([[String:Any]]). And don't use valueForKey – and by the way those silly bridge casts to AnyObject – unless you can explain why you explicitly need KVC.
.allowFragments is not needed because the root object is a collection type.
do {
if let jsonObj = try JSONSerialization.jsonObject(with: data) as? [String:Any],
let postdata = jsonObj["postdata"] as? [[String:Any]] {
for data in postdata {
for (key, value) in data {
print(key, value)
}
}
}
} catch {
print(error)
}

Issue with JSON and Swift - \u00c3\u00a9 é instead of é

I am trying to display some JSON data on my iOS app but I am having an issue with displaying it correctly using Swift.
When I use the normal JSONSerializer for \u00c3\u00a9 i get é but I want to display é. I don't understand if it is an issue with say using UTF-16 rather than UTF-8 or something else?
Does anyone have any suggestions how I would convert \u00c3\u00a9 straight to é in Swift, from a JSON received from an API.
Not sure which encoding you're using, but this code works for both .utf8 and .utf16:
let jsonString = "{\"foo\": \"áéíóú\"}"
let data = jsonString.data(using: .utf16)!
do {
let object = try JSONSerialization.jsonObject(with: data, options: [])
if let dict = object as? [AnyHashable: Any], let text = dict["foo"] as? String {
print("Extracted text: \(text)")
}
}
catch let e {
// TODO: Handle error
print("Error processing JSON: \(e)")
}
was the same problem. Necessary use this code, it works:
Alamofire.request(url, method: .get, parameters: params)
.responseJSON{ response in
guard let data = response.data else {return}
do {
let jsonResult = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! NSDictionary
let json = jsonResult["response_goods"] as! [[String:String]]
print(json) } catch let err as NSError {print(err)
}
}

Json with Swift 2, extracting data

I'm having this issue where I can't access values from JSON response,
the response is : {"result":[true]}
and when the JSON gets it with this code
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)
let result:String = json["result"]
print(result)
}catch {
print("Error with Json: \(error)")
}
I get an error, and the when I did the debug, I saw that json had the following
how json is stored
is there anyway to access the result from json ? it didn't work treating it as an array nor as dictionary
any ideas ?
thanks
result is not String, it's an Array of Bool (represented by the brackets).
Basically do not annotate types unless the compiler needs them.
Cast the JSON to the proper type and use Swift native collection types. It's also recommended to use optional bindings to avoid unexpected crashes.
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments) as? [String:AnyObject],
result = json["result"] as? [Bool] where !result.isEmpty {
print(result[0])
}
} catch {
print("Error with Json: \(error)")
}
Try like this
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments) as! NSDictionary
let result = json["result"] as! NSArray
print(result)
let boole = result[0];
}catch {
print("Error with Json: \(error)")
}