0

I want convert array of dictionaries to a json string so i have used

func json(from object: NSMutableArray) -> String? {
    guard let data = try? JSONSerialization.data(withJSONObject: object) else {
        return nil
    }

    return String(data: data, encoding: String.Encoding.utf8)
}

and it is returning a json string but with an optional before the stirng

finalString = json(from: saveArray)
print(finalString)

Optional("[{\"CreatedOn\":\"Thursday, Mar 29, 2018\",\"DayName\":\"Wed\",\"EmployeeID\":\"1\",\"AppointmentType\":\"3\",\"FromTime\":\"09:00:00\",\"AppointmentDate\":\"Wednesday, May 16, 2018\",\"ToTime\":\"10:00:00\",\"CreatedBy\":\"40289\",\"PatientID\":\"17586\",\"ResourceID\":\"1\",\"PatientConditionId\":\"17590\"},{\"CreatedOn\":\"Thursday, Mar 29, 2018\",\"DayName\":\"Thu\",\"EmployeeID\":\"1\",\"AppointmentType\":\"3\",\"FromTime\":\"09:00:00\",\"AppointmentDate\":\"Thursday, May 17, 2018\",\"ToTime\":\"10:00:00\",\"CreatedBy\":\"40289\",\"PatientID\":\"17586\",\"ResourceID\":\"1\",\"PatientConditionId\":\"17590\"},{\"CreatedOn\":\"Thursday, Mar 29, 2018\",\"DayName\":\"Fri\",\"EmployeeID\":\"1\",\"AppointmentType\":\"3\",\"FromTime\":\"09:00:00\",\"AppointmentDate\":\"Friday, May 18, 2018\",\"ToTime\":\"10:00:00\",\"CreatedBy\":\"40289\",\"PatientID\":\"17586\",\"ResourceID\":\"1\",\"PatientConditionId\":\"17590\"}]")

and when i unwrap this value...

finalString = json(from: saveArray)
print(finalString!)

then I get...

[
{
"CreatedOn": "Thursday, Mar 29, 2018",
"DayName": "Wed",
"EmployeeID": "1",
"AppointmentType": "3",
"FromTime": "09:00:00",
"AppointmentDate": "Wednesday, May 16, 2018",
"ToTime": "10:00:00",
"CreatedBy": "40289",
"PatientID": "17586",
"ResourceID": "1",
"PatientConditionId": "17590"
},
{
"CreatedOn": "Thursday, Mar 29, 2018",
"DayName": "Thu",
"EmployeeID": "1",
"AppointmentType": "3",
"FromTime": "09:00:00",
"AppointmentDate": "Thursday, May 17, 2018",
"ToTime": "10:00:00",
"CreatedBy": "40289",
"PatientID": "17586",
"ResourceID": "1",
"PatientConditionId": "17590"
},
{
"CreatedOn": "Thursday, Mar 29, 2018",
"DayName": "Fri",
"EmployeeID": "1",
"AppointmentType": "3",
"FromTime": "09:00:00",
"AppointmentDate": "Friday, May 18, 2018",
"ToTime": "10:00:00",
"CreatedBy": "40289",
"PatientID": "17586",
"ResourceID": "1",
"PatientConditionId": "17590"
}
]

just an array structure.

now how can i achieve the json string structure without the optional value?????

Fogmeister
  • 76,236
  • 42
  • 207
  • 306
Somenath
  • 19
  • 1
  • 6
  • put ! at the end of String(data: data, encoding: String.Encoding.utf8) – PPL Mar 29 '18 at 09:21
  • no it returns the array structure... but i want this string structure.... "[{\"CreatedOn\":\"Thursday, Mar 29, 2018\",\"DayName\":\"Wed\",\"EmployeeID\":\"1\",\"AppointmentType\":\"3\",\"FromTime\":\"09:00:00\",\"AppointmentDate\":\"Wednesday, May 16, 2018\",\"ToTime\":\"10:00:00\",\"CreatedBy\":\"40289\",\"PatientID\":\"17586\",\"ResourceID\":\"1\",\"PatientConditionId\":\"17590\"}]" – Somenath Mar 29 '18 at 09:30
  • Your problem here seems to be misunderstanding what Optional values are in Swift. I would suggest reading the free Swift book from Apple (there are many other resources) about what Optionals are and how to use them. This will allow you to answer your question :D – Fogmeister Mar 29 '18 at 09:49
  • with all respect i know what is optional value in swift. My question is that when i unwrap the string why the structure changes? – Somenath Mar 29 '18 at 09:57
  • do you want to say "[{"CreatedOn":"Thursday, Mar 29, 2018","DayName":"Wed","EmployeeID":"1","AppointmentType":"3","FromTime":"09:00:00","AppointmentDate":"Wednesday, May 16, 2018","ToTime":"10:00:00","CreatedBy":"40289","PatientID":"17586","ResourceID":"1","PatientConditionId":"17590"}]" this is json string structure in swift? – Somenath Mar 29 '18 at 09:58
  • @Somenath your function returns `String?` if you don't want it to be optional... why are you returning an optional string? – Fogmeister Mar 29 '18 at 10:00
  • How can i achive this structure ? "[{\"CreatedOn\":\"Thursday, Mar 29, 2018\",\"DayName\":\"Wed\",\"EmployeeID\":\"1\",\"AppointmentType\":\"3\",\"FromTime\":\"09:00:00\",\"AppointmentDate\":\"Wednesday, May 16, 2018\",\"ToTime\":\"10:00:00\",\"CreatedBy\":\"40289\",\"PatientID\":\"17586\",\"ResourceID\":\"1\",\"PatientConditionId\":\"17590\"}]" – Somenath Mar 29 '18 at 10:03
  • My concern is not with the optional... i just want to know why the structure get changed if i unwrap it? – Somenath Mar 29 '18 at 10:06
  • OK, just looking at this now. Why are you using an `NSMutableArray`? i.e. why `Mutable`? And why `NSArray`? If you're using Swift you should be using `Array`. – Fogmeister Mar 29 '18 at 10:22
  • Also... what are you actually trying to achieve here? Are you going to be uploading this JSON to an endpoint (or something similar)? – Fogmeister Mar 29 '18 at 10:27
  • Yes we are working with .net apis and the backend guys said that they want the structure with backslashes. otherwise they cannot parse it. – Somenath Mar 29 '18 at 10:45
  • You shouldn't be sending JSON as a string though. You just send the data. The data is then unwrapped on the other end into objects etc... JSON is NOT a String. JSON is a data format to represent "Javascript objects" – Fogmeister Mar 29 '18 at 10:53
  • then what value should i send to the api? Optional("[{\"CreatedOn\":\"Thursday, Mar 29, 2018\",\"DayName\":\"Wed\",\"EmployeeID\":\"1\",\"AppointmentType\":\"3\",\"FromTime\":\"09:00:00\",\"AppointmentDate\":\"Wednesday, May 16, 2018\",\"ToTime\":\"10:00:00\",\"CreatedBy\":\"40289\",\"PatientID\":\"17586\",\"ResourceID\":\"1\",\"PatientConditionId\":\"17590\"}])"...... this one? – Somenath Mar 29 '18 at 11:07
  • No... that's a string. And the `Optional(...)` bit only comes from the debug description of the string (i.e. when you use `print(optionalThing)`). What you should send through the api is the `data` from your function. Don't turn the `data` into a String. Just add the `data` as the request body for your URL request. – Fogmeister Mar 29 '18 at 12:16

2 Answers2

0

You can do it by conditional binding

if let finalString = json(from: saveArray) {
  print(finalString) //here final string is unwrapped
} else {
  print("Invalid JSON")
}

or

guard let finalString = json(from: saveArray) else {
   print("finalString is nil")
   return
}

print(finalString)
Mahendra
  • 8,448
  • 3
  • 33
  • 56
  • no, I want the only string value which is inside the optional like "[{\"CreatedOn\":\"Thursday, Mar 29, 2018\",\"DayName\":\"Wed\",\"EmployeeID\":\"1\",\"AppointmentType\":\"3\",\"FromTime\":\"09:00:00\",\"AppointmentDate\":\"Wednesday, May 16, 2018\",\"ToTime\":\"10:00:00\",\"CreatedBy\":\"40289\",\"PatientID\":\"17586\",\"ResourceID\":\"1\",\"PatientConditionId\":\"17590\"}]" – Somenath Mar 29 '18 at 09:28
  • Use this code and just check the console you will get only string value without "optional" . – Mahendra Mar 29 '18 at 09:46
  • i got the string value but it is without the backslashes. – Somenath Mar 29 '18 at 10:33
  • It is printed on console thats why it has "\" otherwise it won't. – Mahendra Mar 29 '18 at 10:39
0

You declared the return value as optional

... -> String?

so it's always optional even if the result is not.

Unwrap or optional bind the optional

finalString! 

if let final = finalString { ...

to get rid of Optional in the print-out.


A better solution is to mark the function as can throw and hand over the error of JSONSerialization. It's a much more consistent error handling than returning an optional. If there is no error the string created from the Data object can never be nil.

And don't use NSMutableArray in Swift.

func json(from object: [[String:Any]]) throws -> String {
    let data = try JSONSerialization.data(withJSONObject: object)
    return String(data: data, encoding: .utf8)!
}

and use it

do {
   let finalString = json(from: ...
} catch { print(error) }
vadian
  • 274,689
  • 30
  • 353
  • 361
  • I did this earlier and now i double checked it but it returns the same value with optional keyword – Somenath Mar 29 '18 at 09:41
  • Of course you have to put the `json(from` call in a `do - catch` block. Don't ignore errors with `try?` – vadian Mar 29 '18 at 09:43
  • actually why the escape characters are removed from the optional string? – Somenath Mar 29 '18 at 10:15
  • The backslashes are virtual not real. They are only needed to be able to display the entire string as literal string. – vadian Mar 29 '18 at 10:18
  • we are working with .net apis and the backend guys said that they want the structure with backslashes. otherwise they cannot parse it. Now what can i do? – Somenath Mar 29 '18 at 10:28
  • I'm not familiar with the .net stuff but backslashes to escape double quotes are only used in JSON if a value is a literal string containing double quotes. – vadian Mar 29 '18 at 10:33