1

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?

5
  • 3
    This is because your JSONformat is invalid Commented May 30, 2019 at 13:16
  • so it should return empty { } instead of null? Commented May 30, 2019 at 13:18
  • Try to update your JSON as the following: ``` { "Message": { "email": "[email protected]", "id": 56, "nickname": "testNickname" }, "Status": 200, "Result": "success" } ``` Commented May 30, 2019 at 13:23
  • 1
    <null> != null Commented May 30, 2019 at 13:40
  • I did a misstype , it should be null instead of <null> Commented May 30, 2019 at 14:50

3 Answers 3

2

Change this line:

var Message: UpdateNicknameMessage

to this one:

var Message: UpdateNicknameMessage?

Everything will work fine now.

Sign up to request clarification or add additional context in comments.

1 Comment

Simple fix , i like this! I completly forgot about optional value, thanks for your answer.
2

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!!

1 Comment

Only message is optional value ( so i dont need others to be optional too) , but your code should also works.
0

Set all your variables in Structs as optionals.

EX:

var Status: Int?
 var Result: String?
 var Message: UpdateNicknameMessage? ```

1 Comment

Only message is optional so i dont need others to be optional too. Simple var message: updatenicknamemessage? will work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.