ShadeToD
ShadeToD

Reputation: 490

How to handle null value in JSON in SWIFT

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

Answers (3)

Hitesh Surani
Hitesh Surani

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

Mehul Thakkar
Mehul Thakkar

Reputation: 12594

Change this line:

var Message: UpdateNicknameMessage

to this one:

var Message: UpdateNicknameMessage?

Everything will work fine now.

Upvotes: 2

indraneel lagishetty
indraneel lagishetty

Reputation: 11

Set all your variables in Structs as optionals.

EX:

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

Upvotes: 0

Related Questions