davedavedave davedavedave - 1 month ago 93
JSON Question

JSONSerialization with optionals in Swift 3

In Swift 3,

JSONSerialization
of arrays with optional values fails.
This worked in Swift 2 (yielding null as the JSON value of
nil
optionals as would be expected).

Swift 2:

let a: [String!] = ["a","b","c"]
let b: [String] = ["a","b","c"]

let s: String! = "a"
let c = ["a",s]

NSJSONSerialization.isValidJSONObject(a) //true
NSJSONSerialization.isValidJSONObject(b) //true
NSJSONSerialization.isValidJSONObject(c) //true


Swift 3:

let a: [String?] = ["a","b","c"]
let b: [String] = ["a","b","c"]

let s: String! = "a"
let c = ["a",s]

JSONSerialization.isValidJSONObject(a) //false
JSONSerialization.isValidJSONObject(b) //true
JSONSerialization.isValidJSONObject(c) //false


Is this an intended change?
It seems quite error prone as any arrays or dictionaries constructed with an implicit type now potentially are not valid for JSON (even if they do not actually contain any nil values).

Additionally, how can null values then be specified?

Answer

Only NSNull() is serialized to JSON null, not optionals (independent of the Swift version).

An array of optionals could be transformed like this:

let a: [String?] = ["a", nil, "c"]

let b = a.map { $0 as Any? ?? NSNull() }
print(b) // ["a", <null>, "c"]

let d = try! JSONSerialization.data(withJSONObject: b)
print(String(data: d, encoding: .utf8)!) // ["a",null,"c"]
Comments