Expected to decode Int but found a number instead
Solution 1
The error message is very misleading. This happens when the JSON contains a boolean value, and the struct has an Int
property for the corresponding key.
Most likely your JSON actually looks like this:
{
"code": 406,
"message": "Email Address already Exist.",
"status": false
}
and accordingly, your struct should be
struct Registration: Codable {
let code: Int
let status: Bool
}
if let registration = try? JSONDecoder().decode(Registration.self, from: data) {
print(registration.code) // 406
print(registration.status) // false
}
Solution 2
For these kinds of issues, check and make sure that the response and the type of response given in the struct are the same. Here it seems your response is not correct. The status may true or false
{
code: 406,
message: "Email Address already Exist.",
status: 0
}
If the status is true, change your struct as,
struct Registration: Codable {
var code: Int
var status: Bool
var message: String
}
if the status is 0, change the var status: Bool
to var status: Int
, in the above struct.
Solution 3
I think we can use this for resolving such issues:
protocol DecodingHelper {
associatedtype Keys: CodingKey
static func getStringValue(_ container: KeyedDecodingContainer<Keys>, key: Keys) -> String
static func getIntValue(_ container: KeyedDecodingContainer<Keys>, key: Keys) -> Int
static func getBoolValue(_ container: KeyedDecodingContainer<Keys>, key: Keys) -> Bool
}
extension DecodingHelper {
static func getStringValue(_ container: KeyedDecodingContainer<Keys>, key: Keys) -> String {
var str: String = ""
if let obj = try? container.decode(String.self, forKey: key) {
str = obj
}
else if let obj = try? container.decode(Int.self, forKey: key){
str = String(obj)
}
return str
}
static func getIntValue(_ container: KeyedDecodingContainer<Keys>, key: Keys) -> Int {
var val: Int = 0
if let obj = try? container.decode(String.self, forKey: key),
let intVal = Int(obj){
val = intVal
}
else if let obj = try? container.decode(Int.self, forKey: key){
val = obj
}
return val
}
static func getBoolValue(_ container: KeyedDecodingContainer<Keys>, key: Keys) -> Bool {
var val: Bool = false
if let obj = try? container.decode(String.self, forKey: key),
let intVal = Int(obj){
(intVal != 0) ? (val = true) : (val = false)
}
else if let obj = try? container.decode(Int.self, forKey: key){
(obj != 0) ? (val = true) : (val = false)
}
else if let obj = try? container.decode(Bool.self, forKey: key){
val = obj
}
return val
}
}
struct VideoFeedback: Codable {
// MARK:- Variables -
var isFeedbackProvided:Bool = true
// MARK:- Initialisation -
private enum CodingKeys: String, DecodingHelper, CodingKey {
typealias Keys = CodingKeys
case isFeedbackProvided = "lastVideoFeedback"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
isFeedbackProvided = CodingKeys.getBoolValue(values, key: .isFeedbackProvided)
}
}
Let me know if you have any suggestion to improve this.
Solution 4
You don't need to implement your own decoding initializer if your struct's properties are already Decodable
. Neither do you need custom CodingKeys
as mentioned by @Gereon.
For the following JSON data:
let data = """
{
"code": 406,
"message": "Email Address already Exist.",
"status": 0
}
""".data(using: .utf8)!
This works fine:
struct Registration: Codable {
var code: Int
var status: Int
}
if let registration = try? JSONDecoder().decode(Registration.self, from: data) {
print(registration.code) // 406
print(registration.status) // 0
}
See Encoding and Decoding Custom Types from Apple for more information.
![Jatin Chauhan](https://i.stack.imgur.com/ovKNI.jpg?s=256&g=1)
Jatin Chauhan
My skill is to develop native iOS app with using swift or objective c.
Updated on June 15, 2022Comments
-
Jatin Chauhan about 2 years
I had issue with JSON parsing in Swift 4.2. Here is the following code which shown runtime error.
My Json data is as follow which i got from server.
{ code: 406, message: "Email Address already Exist.", status: 0 }
I am using Codable to create my structure as follow
struct Registration: Codable { var code: Int var status: Int private enum CodinggKeys: String, CodingKey { case code case status } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) do { self.code = Int(try container.decode(String.self, forKey: .code))! } catch DecodingError.typeMismatch { let value = try container.decode(Double.self, forKey: .code) self.code = Int(value); } do { self.status = try container.decode(Int.self, forKey: .status) } catch DecodingError.typeMismatch { let value = try container.decode(String.self, forKey: .status) self.status = Int(value); } } }
But every time i got error on parsing status key.
Note: I had tried to parse status in String, Int, Double, Decimal, NSInterger but neither any works. every time i got the same error. Expected to decode UInt but found a number instead.