Кодируемый разбор - PullRequest
       6

Кодируемый разбор

0 голосов
/ 09 февраля 2019

Я пытаюсь проанализировать ответ API с использованием класса Codable.

Ниже приведен ответ:

{"status":200,"message":"","success":1,"data":[{"event_id":"26","event_name":"Mens Night","event_desc":"Hot Mens Night","from_date":"2019-02-08","to_date":"2019-03-09","bar_id":"62","bar_names":"Autumn Bar & Bistro","bar_ids":"62","offer_image":"https:\/\/www.tippler.app\/manager\/uploads\/events\/mens_night.jpg","from_time":"19:00:00","to_time":"01:30:00"},{"event_id":"36","event_name":"Karaoke Night","event_desc":"Karaoke NIght with Brian Rub","from_date":"2019-02-08","to_date":"2019-02-09","bar_id":"146","bar_names":"Amuse Resto Bar","bar_ids":"146","offer_image":"https:\/\/www.tippler.app\/manager\/uploads\/events\/Screenshot_20190208-155223__011.jpg","from_time":"21:00:00","to_time":"01:00:00"},{"event_id":"37","event_name":"Sufi Nights","event_desc":"Singers From mumbai","from_date":"2019-02-08","to_date":"2019-02-09","bar_id":"66","bar_names":"Cavalry The Lounge","bar_ids":"66","offer_image":"https:\/\/www.tippler.app\/manager\/uploads\/events\/SUFI-FEATURED.jpg","from_time":"20:00:00","to_time":"01:30:00"},{"event_id":"39","event_name":"BOLLYWOOD NIGHT","event_desc":"BHANGRA AND LIVE DHOL","from_date":"2019-02-09","to_date":"2019-02-10","bar_id":"103","bar_names":"B Desi","bar_ids":"103","offer_image":"https:\/\/www.tippler.app\/manager\/uploads\/events\/bollywood-nights-1.jpg","from_time":"21:00:00","to_time":"01:00:00"}],"error_dev":""}

I Класс Codable:

struct Events: Codable {
    var event_id: String
    var event_name: String
    var event_desc: String
    var from_date: String
    var to_date: String
    var bar_id: String
    var bar_names: String
    var bar_ids: String
    var offer_image: String
    var from_time: String
    var to_time: String

    enum CodingKeys: String, CodingKey {
        case event_id = "event_id"
        case event_name = "event_name"
        case event_desc = "event_desc"
        case from_date = "from_date"
        case to_date = "to_date"
        case bar_id = "bar_id"
        case bar_names = "bar_names"
        case bar_ids = "bar_ids"
        case offer_image = "offer_image"
        case from_time = "from_time"
        case to_time = "to_time"
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(event_id, forKey: .event_id)
        try container.encode(event_name, forKey: .event_name)
        try? container.encode(event_desc, forKey: .event_desc)
        try? container.encode(from_date, forKey: .from_date)
        try container.encode(to_date, forKey: .to_date)
        try container.encode(bar_id, forKey: .bar_id)
        try container.encode(bar_names, forKey: .bar_names)
        try container.encode(bar_ids, forKey: .bar_ids)
        try container.encode(offer_image, forKey: .offer_image)
        try container.encode(from_time, forKey: .from_time)
        try container.encode(to_time, forKey: .to_time)
    }


    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        event_id = try values.decode(String.self, forKey: .event_id)
        event_name = try values.decode(String.self, forKey: .event_name)
        event_desc = try values.decode(String.self, forKey: .event_desc)
        from_date = try values.decode(String.self, forKey: .from_date)
        to_date = try values.decode(String.self, forKey: .to_date)
        bar_id = try values.decode(String.self, forKey: .bar_id)
        bar_names = try values.decode(String.self, forKey: .bar_names)
        bar_ids = try values.decode(String.self, forKey: .bar_ids)
        offer_image = try values.decode(String.self, forKey: .offer_image)
        from_time = try values.decode(String.self, forKey: .from_time)
        to_time = try values.decode(String.self, forKey: .to_time)
    }


}

Itвозвращается с ошибкой ответа

keyNotFound (CodingKeys (stringValue: "event_id", intValue: nil), Swift.DecodingError.Context (codingPath: [CodingKeys> (stringValue: "data", intValue:nil), _JSONKey (stringValue: "Index 0", intValue: 0)], debugDescription: "Нет значения, связанного с ключом CodingKeys (stringValue: \" event_id \ ", intValue: nil) (\" event_id \ ").",ringError: nil))

, пожалуйста, предложите мне решение.

Ответы [ 3 ]

0 голосов
/ 09 февраля 2019
struct Events : Codabel {
   let status: Int?
   let message: String?
   let success: Int?
   let data: [Event]?
   let errorDev: String?
}

struct Datum: Codable {
    let eventID, eventName, eventDesc, fromDate, offerImage, fromTime, toTime : String?
    let toDate, barID, barNames, barIDs: String?
}

нет необходимости записывать CodingKeys для случаев со змеями,

При декодировании вы просто пишете

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let responseModel = try decoder.decode(Events.self, from: data) // data from response 
0 голосов
/ 09 февраля 2019

В вашем коде есть несколько ошибок, как следует ...

  • event_id имеет тип String в вашем коде, но имеет тип Int.
  • bar_id имеет тип String в вашем коде, но имеет тип Int.
  • bar_ids имеет тип String в вашем коде, но имеет тип Int.

Вам необходимо исправить эти типы переменных.

Примечание. Где бы в ответе вы не находили число, оно будет иметь тип Int, число с десятичными точками, например 12.123.тогда if будет иметь тип Double по умолчанию.Непосредственное допущение, что это строка, в swift недопустимо.

0 голосов
/ 09 февраля 2019

Ваша кодируемая структура не совпадает с ответом, поскольку они имеют статус, успех сообщения и ключ errorDev

Попробуйте это

struct Response: Codable {
    let status: Int?
    let message: String?
    let success: Int?
    let data: [Events]?
    let errorDev: String?

    enum CodingKeys: String, CodingKey {
        case status, message, success, data
        case errorDev = "error_dev"
    }
}
struct Events: Codable {
    let eventID, eventName, eventDesc, fromDate: String?
    let toDate, barID, barNames, barIDs: String?
    let offerImage: String?
    let fromTime, toTime: String?

    enum CodingKeys: String, CodingKey {
        case eventID = "event_id"
        case eventName = "event_name"
        case eventDesc = "event_desc"
        case fromDate = "from_date"
        case toDate = "to_date"
        case barID = "bar_id"
        case barNames = "bar_names"
        case barIDs = "bar_ids"
        case offerImage = "offer_image"
        case fromTime = "from_time"
        case toTime = "to_time"
    }
}

РЕДАКТИРОВАТЬ

Я могу предоставить вам более общее решение.Предположим, что все API имеют одинаковый ответ, но только ключ data отличается от

struct GeneralResponse<T:Codable>: Codable {
     let status: Int?
     let message: String?
     let success: Int?
     let data: T?
     let errorDev: String?

    enum CodingKeys: String, CodingKey {
        case message = "msg"
        case code = "code"
        case data = "data" 
      // add more keys
    }

    public init(from decoder:Decoder) throws {
        let contaienr = try  decoder.container(keyedBy: CodingKeys.self)
        message = try contaienr.decode(String.self, forKey: .message)
        // Decode Other keys 

        do {
            let object = try contaienr.decodeIfPresent(T.self, forKey: .data)
            data = object

        } catch {
            data = nil
        }

    }

}

Теперь Для каждого ответа вы можете

использовать GenericResponse<[Event]> или GenericResponse<Login> или GenericResponse<[UserList]>

Надеюсь, это полезно

...