Search code examples
jsonswiftcodableencodable

Swift Codable Protocol. String encoding issue


Recently I have faced an issue while encoding an entity, which conforms to Codable protocol.

Here is the code for the Playground:

class Person: Codable {
    var name: String?
    var age: Int?
    var isDev: Bool?
}

let p1 = Person()
p1.name = "John N."
p1.age = 13
p1.isDev = false

let p2 = Person()
p2.name = "Jack"
p2.age = 19
p2.isDev = true

let people = [p1, p2]
let data = try JSONEncoder().encode(people)
let j = try! JSONSerialization.jsonObject(with: data, options: [])

print(j)

This is the output I am getting in the Playground console:

enter image description here

As you can see, the encoded p1 name has the quotation marks, but the p2 doesn't. So my question is why?

P.S. The only one thing I have noticed is that adding e.g. a space symbol or an underscore anywhere when setting the string value adds quotation marks in json. the p1.name contains a space, so it is encoded properly.

Any thoughts are appreciated.


Solution

  • j is the deserialised JSON object, not the JSON string (encoded data). If you want to see the JSON, convert data to a string, as that is the JSON:

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

    j is actually the representation of your JSON data using NSArrays and NSDictionarys. It turns out that if you print NSDictionarys with strings in them, quotes will be added to strings that have spaces and/or other special characters, to tell you where the string actually starts and ends.

    Compare:

    print(["name": "hello"] as NSDictionary)
    print(["name": "hello world"] as NSDictionary)
    print(["hello"] as NSArray)
    print(["hello world"] as NSArray)
    

    Output:

    {
        name = hello;
    }
    {
        name = "hello world";
    }
    (
        hello
    )
    (
        "hello world"
    )