The data couldn’t be read because it is missing error when decoding JSON in Swift
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.
JSON API Error- The data couldn’t be read because it is missing.- in iOS, swift
First of all the Codable
models that you're using is missing the root level object of the JSON. So, you must use
struct Root: Codable {
let items: [Items]
}
struct Items: Codable {
let title:String?
let snippet:String?
let pagemap : PageMap?
}
struct PageMap: Codable {
let cseImage: [Thumbnail]?
}
struct Thumbnail: Codable {
let src: String?
}
Important:
- No need for
enum CodingKeys
if the property names exactly match the JSON keys. - No need for
init(from:)
if you're not doing any specific parsing. - Don't use
var
when not required. Uselet
instead while declaring the properties. - If you're using
convertFromSnakeCase
while parsing, you must create the property names in camel-case (without underscore).
Next, your parsing code in URLSession
must go like,
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let data = data {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let res = try decoder.decode(Root.self, from: data)
//rest of the code...
}
}
Problem while converting JSON to Swift The data couldn’t be read because it isn’t in the correct format.
First of all
never print(error.localizedDescription)
.
in a JSONDecoder
catch block. You get a generic but quite meaningless error message.
Always print the entire error, DecodingError
s are very descriptive
print(error)
Your code contains three major errors, one of them (error #3) occurs multiple times
Error #1
typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))
indicates that the root object is an array, the JSON starts clearly with [
Solution: Decode [CryptListStruct].self
Error #2
dataCorrupted(Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "volume_1mth_usd", intValue: nil)], debugDescription: "Parsed JSON number <3699822674922524.74> does not fit in Int.", underlyingError: nil))
indicates that the received value 3699822674922524.74
is actually a Double
.
Solution: Declare
let volume1MthUsd: Double
Error #3
keyNotFound(CodingKeys(stringValue: "id_icon", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 4", intValue: 4)], debugDescription: "No value associated with key CodingKeys(stringValue: "id_icon", intValue: nil) ("id_icon").", underlyingError: nil))
indicates that the key id_icon
is missing (at least) in the 5th item of the array.
Solution: Declare the type as optional
let idIcon : String?
The same error occurs for dataTradeStart
, dataTradeEnd
, dataQuoteStart
, dataQuoteEnd
, dataOrderbookStart
, dataOrderbookEnd
, dataStart
, dataEnd
let dataQuoteStart, dataQuoteEnd, dataOrderbookStart, dataOrderbookEnd: String?
let dataTradeStart, dataTradeEnd : String?
let dataStart, dataEnd: String?
Side note:
You can delete the entire CodingKeys enum if you replace assetID
with assetId
and add the convertFromSnakeCase
key decoding strategy
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let crpytList = try decoder.decode([CryptListStruct].self, from: data)
Swift - The data couldn’t be read because it isn’t in the correct format
Try this
let gitData = try decoder.decode(Root.self, from: data!)
Traverse through your data
for singleData in gitData.data where (singleData.name ?? "") == "Cafe" {
print(singleData.image)
}
Swift The data couldn’t be read because it isn’t in the correct format
Your JSON format doesn't quite match what you're trying to decode. You need a wrapper for the latest_photos
array at the root of your JSON object.
For example:
struct LatestPhotosWrapper: Codable {
let latestPhotos: [LatestPhoto]
enum CodingKeys: String, CodingKey {
case latestPhotos = "latest_photos"
}
}
let apod = try JSONDecoder().decode(LatestPhotosWrapper.self, from: data)
(Rather than providing a CodingKey
, you can also look into the built-in systems for converting from snake case: https://developer.apple.com/documentation/foundation/jsondecoder/keydecodingstrategy/convertfromsnakecase)
Also, you may want to print the error
and not just the error.localizedDescription
-- you can get a better picture of what's going on. For example, with your original code, you get:
Expected to decode Array but found a dictionary instead.
Finally, you might check out app.quicktype.io -- you can paste in your JSON and get correct Swift structs pre-built for you.
The data couldn’t be read because it is missing. GET Request
You have to add this in your DriverProfileStruct
struct. Because in codable you have to decode key using CodingKey if is different from your variable name
enum CodingKeys: String, CodingKey {
case autoType = "auto_type"
}
Related Topics
iOS App Deployment Without Appstore
Create a Button Programmatically and Set a Background Image
A Launch Storyboard or Xib Must Be Provided Unless the App Requires Full Screen
How to Add Text Input in Alertview of iOS 8
How to Convert .Dae to .Scn Files in Scenekit
Which Tasks Are More Suitable to Nsoperation Than Gcd
Creating a 3X3 Grid with Auto Layout Constraints
Detecting Active Avaudiosessions on iOS Device
iOS Tesseract Ocr Image Preperation
Xcode 8, iOS 10 - "Starting Webfilter Logging for Process"
How to Open Location Services Screen from Setting Screen
iOS 9 - "Attempt to Delete and Reload the Same Index Path"
iOS - Uiimagewritetosavedphotosalbum
Nsuserdefaults Unreliable in iOS 8
Why Tesseract Ocr Library (Ios) Cannot Recognize Text at All