How to create JSON from a dictionary in Swift 4?

Viewed 16763

Edit: I have read the other answers on SO for the same issue , however Im unable to get the desired output. I have tried many variations as suggested in other questions but its not working.

I have a JSON snipped which needs to be added as the body when I open a websocket.

sender: "system1@example.com",
recipients:"system2@example.com",
data: {
    text: "Test Message"
},

So using Swift I did the following,

var messageDictionary : [String: Any] = [
    "sender": "system1@example.com",
    "recipients":"system2@example.com",
    "data": [
        "text": "Test Message"
    ],
]
do {
    let jsonData = try JSONSerialization.data(withJSONObject: messageDictionary, options: .prettyPrinted)
    let jsonString = String(data: jsonData, encoding: String.Encoding.ascii)
    socket.write(string: jsonString!)
    print(jsonString)
} catch {
    print(error.localizedDescription)
}

When I print the jsonString, I get

Optional("{\n  \"sender\" : \"system1@example.com\",\n  \"data\" : {\n    
    \"text\" : \"Test Message\"\n  },\n  \"recipients\" : 
    \"system2@example.com\"\n}")

as the console output. I expected the above snippet to be formatted as JSON. How to get the output as normal JSON without the /n and additional spaces? Im using Swift 4 and Xcode 9.1

Edit 2:

let jsonData = try JSONSerialization.data(withJSONObject: messageDictionary, options: []) let decoded = try JSONSerialization.jsonObject(with: jsonData, options: [])

I tried doing the above and I get the following as the output:

{
    data =     {
        text = Test Message;
    };
    recipients = "system1@example.com";
    sender = "system2@example.com";
}

However the websocket expects this:

{ "sender":"system1@example.com","recipients":
["system2@example.com"],"data":{"text":"Test Message"}}

Even with a slight variation like misplacing of double quotes the websocket server doesnt accept the input. How to exactly format the JSOn this way so that the websocket can accept it?

3 Answers

After trying out various ways, the below way is what worked for me for getting the exact format required by the backend.

var messageDictionary = [
    "sender":"system1@example.com",
    "recipients":[
        "system2@example.com"
    ],
    "data":[
        "text" : data
    ]
] as [String : Any]

let jsonData = try! JSONSerialization.data(withJSONObject: messageDictionary)
let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)

Additionally, you can just cast to String

let jsonData = try? JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
let jsonString = String(data: jsonData!, encoding: .utf8)

Now JSONEncoder can do the work easily.

let encoder = JSONEncoder()

encoder.outputFormatting = .prettyPrinted

let data = try encoder.encode(yourDictionary)

print(String(data: data, encoding: .utf8)!)
Related