NSJSONSerialization error when encoding encodable struct in Swift 5, iOS 14: Invalid top-level type in JSON write

691 Views Asked by At

I have created a simple struct:

struct CodePair: Codable {
    var userId: Int
    var code: String
}

I try to encode the struct into JSON using the code below:

let id = 5
let code = "ABCDEF"

let codePair = CodePair(userId: id, code: code)
let json = try? JSONSerialization.data(withJSONObject: codePair)
print(json)

And I get the following error:

terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write'
terminating with uncaught exception of type NSException
CoreSimulator 732.17 - Device: iPhone 8 (1ADCB209-E3E6-446F-BC41-3A02B418F7CE) - Runtime: iOS 14.0 (18A372) - DeviceType: iPhone 8

I have several structs set up almost identically, and none of them are experiencing this issue. Does anyone have any idea what's going on here?

(Of course, this is part of a much larger async call to an API, but this is the problematic code.)

1

There are 1 best solutions below

1
On BEST ANSWER

You are using the wrong encoder. You should use JSONEncoder encode method not JSONSerialization.data(withJSONObject:)

let id = 5
let code = "ABCDEF"

let codePair = CodePair(userId: id, code: code)
do {
    let data = try JSONEncoder().encode(codePair)
    print(String(data: data, encoding: .utf8)!)
} catch {
    print(error)
}

This will print:

{"userId":5,"code":"ABCDEF"}

The method you were trying to use expects a dictionary or an array:

let jsonObject: [String: Any] = ["userId":5,"code":"ABCDEF"]
do {
    let jsonData = try JSONSerialization.data(withJSONObject: jsonObject)
    print(String(data: jsonData, encoding: .utf8)!)  // {"userId":5,"code":"ABCDEF"}
} catch {
    print(error)
}