Reputation: 490
I have a problem with JSON decoding. I have UpdateNickname and UpdateNicknameMessage structs and variable Message inside UpdateNickname could be a null. I got an error whenever it is a null. I want to handle this problem. Here is my struct:
struct UpdateNicknameMessage: Codable {
let id: Int
let nickname: String
let email: String
}
struct UpdateNickname: Codable {
var Status: Int
var Result: String
var Message: UpdateNicknameMessage
enum CodingKeys: String, CodingKey {
case Status = "Status"
case Result = "Result"
case Message = "Message"
}
init?(from jsonObject: AnyObject) {
guard let Status1: Int = jsonObject.object(forKey: "Status") as? Int,
let Result1: String = jsonObject.object(forKey: "Result") as? String,
let Message1: UpdateNicknameMessage = jsonObject.object(forKey: "Message") as? UpdateNicknameMessage
else { return nil }
Status = Status1
Result = Result1
Message = Message1
}
}
and JSON looks like this:
{"Message": {
email = "[email protected]";
id = 56;
nickname = testNickname;
},
"Status": 200,
"Result": success}
And this is my code for decoding JSON in swift. I use try catch to handle my error.
let decoder = JSONDecoder()
do {
let model = try decoder.decode(UpdateNickname.self, from: data)
let serverStatus = model.Status
if serverStatus == 200 {
//EVERYTHING IS FINE
} else {
//server not working
}
} catch {
//cant convert JSON into struct
print(error.localizedDescription)
}
so my variable Message can return null if something goes wrong with the server.
{"Message": null,
"Status": 400,
"Result": problem}
When i try to decode JSON when Message is null i get an error
The data couldn’t be read because it is missing.
How can i fix this problem and handle null value?
Upvotes: 1
Views: 4932
Reputation: 13537
You can handle it making as optional
. Please refer below model class.
struct UpdateNicknameMessage : Codable {
let email : String?
let id : Int?
let nickname : String?
enum CodingKeys: String, CodingKey {
case email = "email"
case id = "id"
case nickname = "nickname"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
email = try values.decodeIfPresent(String.self, forKey: .email)
id = try values.decodeIfPresent(Int.self, forKey: .id)
nickname = try values.decodeIfPresent(String.self, forKey: .nickname)
}
}
struct UpdateNickname : Codable {
let message : UpdateNicknameMessage?
let status : Int?
let result : String?
enum CodingKeys: String, CodingKey {
case message = "Message"
case status = "Status"
case result = "Result"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
message = try values.decodeIfPresent(Message.self, forKey: .Message)
status = try values.decodeIfPresent(Int.self, forKey: .Status)
result = try values.decodeIfPresent(String.self, forKey: .Result)
}
}
I suggest to use json4swift to create model class from JSON response.
Update:
I think you need to more clear about the usage codable protocol first. Consider, Your server is giving Internal server error
due to any XYZ reason. I think your approach is not worked for it.
I am sure it will give a same error.
The data couldn’t be read because it is missing.
So my first question is
How you could manage in such type of situation?
That's it from my end!!
Happy codding!!
Upvotes: 2
Reputation: 12594
Change this line:
var Message: UpdateNicknameMessage
to this one:
var Message: UpdateNicknameMessage?
Everything will work fine now.
Upvotes: 2
Reputation: 11
Set all your variables in Structs as optionals.
EX:
var Status: Int?
var Result: String?
var Message: UpdateNicknameMessage? ```
Upvotes: 0