I am getting the following error :
The data couldn’t be read because it is missing.
When I run the following code:
struct Indicator: Decodable {
"The data couldn’t be read because it is missing"
the error coming from this code:
...catch {
print(error.localizedDescription)
}
Because: seems that a key is missing or mistyped.
You can check which key is missing by coding like this:
...catch {
debugPrint(error)
}
Note: If struct keys are different from JSON data keys, see below example: the key in struct is 'title' but in data is 'name'.
struct Photo: Codable {
var title: String
var size: Size
enum CodingKeys: String, CodingKey
{
case title = "name"
case size
}
}
If you mistype 'name', the error will pop up.
Also, if you mistype this 'CodingKeys', you will get the error.
enum CodingKeys:...
Printing error.localizedDescription
is misleading because it displays only a quite meaningless generic error message.
So never use localizedDescription
in Decodable
catch blocks.
In the simple form just
print(error)
It shows the full error including the crucial information debugDescription
and context
.Decodable
errors are very comprehensive.
While developing code you could catch each Decodable
error separately for example
} catch let DecodingError.dataCorrupted(context) {
print(context)
} catch let DecodingError.keyNotFound(key, context) {
print("Key '\(key)' not found:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch let DecodingError.valueNotFound(value, context) {
print("Value '\(value)' not found:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch let DecodingError.typeMismatch(type, context) {
print("Type '\(type)' mismatch:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch {
print("error: ", error)
}
It shows only the most significant information.
I just solved a similar issue on my end but for the property list decoder.
The error in this case seems to mean that a key wasn't found and not the data as a whole.
Try making the variables in your struct optional and it should return a nil value where the problem lies.
First make the properties optional then
If your case similar to this try this decodeIfPresent
`public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
firstName = try container.decodeIfPresent(String.self, forKey: .firstName)
}`
Try printing the actual error instead of just the description. It should give you a message like "No value associated with key someKey (\"actual_key_if_you_defined_your_own\")."
, which is much more useful than the localizedDescription
.