Как правильно декодировать эту строку json, используя декодируемую? - PullRequest
0 голосов
/ 22 января 2020

У меня есть следующая json строка:

{"weight":[{"bmi":24.75,"date":"2020-01-20","logId":1000,"source":"API","time":"23:59:59","weight":200}]}

Я хочу преобразовать его в объект Swift для доступа к различным значениям. Вот что я пытаюсь сделать, у меня есть эти настройки структуры:

struct FitbitResponseModel: Decodable  {
    let weight: [FitbitResponseData]
}


struct FitbitResponseData: Decodable  {
    let bmi: Int
    let date: String
    let logId: Int
    let source: String
    let time: String
    let weight: Int
}

И затем у меня есть этот метод для декодирования строки json:

func parseJSON(data: Data) -> FitbitResponseModel? {

    var returnValue: FitbitResponseModel?
    do {
        returnValue = try JSONDecoder().decode(FitbitResponseModel.self, from: data)
    } catch {
        print("Error took place: \(error.localizedDescription).")
    }

    return returnValue
}

Однако, когда я попробуйте запустить его, я получаю сообщение об ошибке, что данные не могут быть прочитаны, потому что они не в правильном формате. Что я делаю неправильно? Любая помощь приветствуется.

Заранее спасибо!

Ответы [ 4 ]

2 голосов
/ 23 января 2020

изменить

let bmi: Int 

на

let bmi: Double 

, поскольку в вашем ответе значение равно 24,75, если какой-либо тип переменной не соответствует JSON всей модели ответа не будет отображаться в протоколе Codable (Encodable и Decodable)

2 голосов
/ 22 января 2020

Json недопустимо, потому что logId значение в вашем json недопустимо.

{
    "weight": [{
        "bmi": 24.75,
        "date": "2020-01-20",
        "logId": 100,
        "source": "API",
        "time": "23:59:59",
        "weight": 200
    }]
}
2 голосов
/ 22 января 2020

Поговорите со своим разработчиком API. 000 не является допустимым представлением числа для json. Это должно быть 0 или 0.0. Вы можете пометить свой json на https://jsonlint.com. Если вам действительно нужно обойти эту проблему, я предлагаю выполнить замену строки на 000, на 0,, прежде чем анализировать данные.

0 голосов
/ 23 января 2020

Одна действительно полезная особенность этого автоматически сгенерированного соответствия состоит в том, что если вы определяете перечисление в вашем типе с именем «CodingKeys» (или используете псевдоним типа с этим именем), которое соответствует протоколу CodingKey - Swift автоматически использует это как тип ключа. Таким образом, это позволяет вам легко настраивать ключи, с которыми ваши свойства кодируются / декодируются.

struct Base: Codable {
    let weight : [Weight]?

    enum CodingKeys: String, CodingKey {
        case weight = "weight"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        weight = try values.decodeIfPresent([Weight].self, forKey: .weight)
    }
}

struct Weight : Codable {
    let bmi : Double?
    let date : String?
    let logId : Int?
    let source : String?
    let time : String?
    let weight : Int?

    enum CodingKeys: String, CodingKey {
        case bmi = "bmi"
        case date = "date"
        case logId = "logId"
        case source = "source"
        case time = "time"
        case weight = "weight"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        bmi = try values.decodeIfPresent(Double.self, forKey: .bmi)
        date = try values.decodeIfPresent(String.self, forKey: .date)
        logId = try values.decodeIfPresent(Int.self, forKey: .logId)
        source = try values.decodeIfPresent(String.self, forKey: .source)
        time = try values.decodeIfPresent(String.self, forKey: .time)
        weight = try values.decodeIfPresent(Int.self, forKey: .weight)
    }
}

Надеюсь, что это поможет!

или вы можете использовать Swifty JSON lib: https://github.com/SwiftyJSON/SwiftyJSON

...