According to the JSON standard RFC 7159, this is valid json:
22
How do I decode this into an Int using swift4's decodable? This does not work
let twentyTwo = try? JSONDecoder().decode(Int.self, from: "22".data(using: .utf8)!)
It works with good ol' JSONSerialization
and the .allowFragments
reading option. From the documentation:
allowFragments
Specifies that the parser should allow top-level objects that are not an instance of NSArray or NSDictionary.
Example:
let json = "22".data(using: .utf8)!
if let value = (try? JSONSerialization.jsonObject(with: json, options: .allowFragments)) as? Int {
print(value) // 22
}
However, JSONDecoder
has no such option and does not accept top-level
objects which are not arrays or dictionaries. One can see in the
source code that the decode()
method calls
JSONSerialization.jsonObject()
without any option:
open func decode<T : Decodable>(_ type: T.Type, from data: Data) throws -> T {
let topLevel: Any
do {
topLevel = try JSONSerialization.jsonObject(with: data)
} catch {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: error))
}
// ...
return value
}
In iOS 13.1+ and macOS 10.15.1+ JSONDecoder
can handle primitive types on root level.
See the latest comments (Oct 2019) in the linked article underneath Martin's answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With