Как обрабатывать нулевое значение в JSON в SWIFT

У меня проблема с декодированием JSON. У меня есть структуры Обновитьникнейм и ОбновитьПсевдонимСообщение, а переменная Сообщение внутри Обновитьникнейм может быть нулевой. Я получаю сообщение об ошибке всякий раз, когда оно равно нулю. Я хочу справиться с этой проблемой. Вот моя структура:

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

и JSON выглядит так:

{"Message": {
    email = "[email protected]";
    id = 56;
    nickname = testNickname;
}, 
 "Status": 200, 
 "Result": success}

А это мой код для декодирования JSON в swift. Я использую try catch, чтобы обработать свою ошибку.

            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)
            }

поэтому моя переменная Сообщение может возвращать значение null, если что-то пойдет не так с сервером.

{"Message": null, 
 "Status": 400, 
 "Result": problem}

Когда я пытаюсь декодировать JSON, когда Сообщение имеет значение null, я получаю сообщение об ошибке

The data couldn’t be read because it is missing.

Как я могу решить эту проблему и обработать нулевое значение?

Это потому, что ваш формат JSON недействителен

Marwen Doukh 30.05.2019 15:16

поэтому он должен возвращать пустой {} вместо нуля?

ShadeToD 30.05.2019 15:18

Попробуйте обновить свой JSON следующим образом: ``` { "Сообщение": { "email": "[email protected]", "id": 56, "nickname": "testNickname" }, "Status": 200 , "Результат": "успех" } ```

Marwen Doukh 30.05.2019 15:23
<null> != null
Grady Player 30.05.2019 15:40

Я сделал пропущенный тип, он должен быть нулевым вместо <null>

ShadeToD 30.05.2019 16:50
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
5
2 715
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Установите все свои переменные в Structs как необязательные.

БЫВШИЙ:

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

Только сообщение является необязательным, поэтому мне не нужно, чтобы другие были необязательными. Простое сообщение var: updatenicknamemessage? буду работать.

ShadeToD 30.05.2019 16:40

Вы можете справиться с его изготовлением как optional. Пожалуйста, обратитесь к классу модели ниже.

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)
    }

}

Я предлагаю использовать json4swift для создания класса модели из ответа JSON.

Обновлять:

Я думаю, вам нужно сначала более четко определить использование кодируемого протокола. Учтите, что ваш сервер дает Internal server error по любой причине XYZ. Я думаю, что ваш подход не работает для этого.

Я уверен, что это даст ту же ошибку.

The data couldn’t be read because it is missing.

Итак, мой первый вопрос

Как вы могли бы справиться в такой ситуации?

Это с моей стороны!!

Удачного кодинга!!

Только сообщение является необязательным значением (поэтому мне не нужно, чтобы другие были необязательными), но ваш код также должен работать.

ShadeToD 30.05.2019 16:39
Ответ принят как подходящий

Измените эту строку:

var Message: UpdateNicknameMessage

к этому:

var Message: UpdateNicknameMessage?

Теперь все будет работать нормально.

Простое решение, мне это нравится! Я совсем забыл о необязательном значении, спасибо за ваш ответ.

ShadeToD 30.05.2019 16:38

Другие вопросы по теме