Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"The data couldn’t be read because it is missing" error when decoding JSON in Swift

Tags:

json

ios

swift

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 {     let section: String     let key: Int     let indicator: Int     let threshold: Int }     var indicators = [Indicator]()      do {         if let file = Bundle.main.url(forResource: "indicators", withExtension: "json") {             indicators = try JSONDecoder().decode([Indicator].self, from: try Data(contentsOf: file))         }     } catch {         print(error.localizedDescription)     } 

These are in a function, but I have removed them for clarity. I have a code block which is very similar in a different file (I copied this code from there and changed the names essentially) so I'm not sure why it's happening. The json file is valid json and has it's target properly set.

Thanks

like image 591
Jalem Avatar asked Oct 26 '17 16:10

Jalem


2 Answers

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.

like image 160
vadian Avatar answered Sep 18 '22 10:09

vadian


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.

like image 38
Tyler Avatar answered Sep 21 '22 10:09

Tyler