Top-level \(T.self) encoded as number JSON fragment

I tried to directly encode an enum to json. I get the following error: "Top-level (T.self) encoded as number JSON fragment.".
I looked up the corresponding source line in the Swift sources: https://github.com/apple/swift/blob/master/stdlib/public/SDK/Foundation/JSONEncoder.swift#L221

Judging from the code, it looks like it's only possible to encode structs/dictionaries/arrays to json with the JSONEncoder. Is this true?

Would you mind to provide a small code snippet to play around with the issue?

Here you go:

enum E: Int, Codable {
	case one
}

do {
	try JSONEncoder().encode(E.one)
}
catch {
	print("\(error)") // "Top-level E encoded as number JSON fragment."
}

Yes, this is true for now. JSONEncoder uses JSONSerialization to serialize into JSON, and JSONSerialization requires the top-level values to not be fragments (i.e. they must be containers).

If you can, please file a bug and we can consider expanding this, either at the JSONSerialization or JSONEncoder level.

2 Likes

Sure, I love filing bugs, as long as it's no black-hole radar ;-) WWDC16 - Videos - Apple Developer

https://bugs.swift.org/browse/SR-7213

3 Likes

@itaiferber Do we have any updates on the progress of [SR-6163] JSONDecoder cannot decode RFC 7159 JSON · Issue #4402 · apple/swift-corelibs-foundation · GitHub (which [SR-7213] Allow JSONEncoder to Encode Top-Level Fragments · Issue #4038 · apple/swift-corelibs-foundation · GitHub dupes)?

This seems like it might not be such a trivial update to .allowFragments since encoding/decoding requires the existence of containers. Though you might consider this case to use a singleValueContainer. Let's at least start discussing this again.

Yes, @bendjones has worked on this internally, though this is not aligned with Swift 5 proper. No specific promises, but we’d like to land this in the Swift 5.x timeframe.

3 Likes

Thanks for the update. Glad to know that it hasn't been forgotten.

2 Likes