davedavedave davedavedave - 3 months ago 127
JSON Question

JSONSerialization with optionals in Swift 3

In Swift 3,

of arrays with optional values fails.
This worked in Swift 2 (yielding null as the JSON value of
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?


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"]