Отображение объекта класса с использованием TranfsformType в ObjectMapper в Swift - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть JSON как

{
  "code": 200,
  "status": "success",
  "data": [
    {
      "cardTypeId": 1,
      "cardInfo": {
        "background": "#4267b2",
        "userName": "abkur_rt",
        "text": "Hello Video",
        "media": {
          "mediaUrl": "",
          "mediaType": "image",
          "mediaThumbUrl": ""
        }
      }
    },
    {
      "cardTypeId": 4,
      "cardInfo": {
        "text": "Image and text",
        "media": {
          "mediaUrl": "",
          "mediaType": "image",
          "mediaThumbUrl": ""
        }
      }
    }
  ]
}

Для анализа этого я использовал ObjectMapper (https://github.com/tristanhimmelman/ObjectMapper) Мой запрос заключается в том, что в моем JSON я получаю cardInfo в зависимости от cardTypeId Так что ясделал классы, ссылающиеся на эту ссылку ObjectMapper, как отобразить другой объект на основе JSON , чтобы понять, как использовать собственный TransformType для классов. В ответе JSON ссылки есть Array, но в моем случае, если cardTypeId равно 1, тогдаесть еще 2 поля, в которых все то же самое в cardInfo. Поэтому я создал классы, как показано ниже, но я не уверен, как я буду создавать класс, наследующий TransFormType.

class LBDetailsList: Mappable {

    var lbListArray : [LBDetail]?

    required init?(map: Map) {

    }

    func mapping(map: Map) {
        lbListArray <- map ["data"]
    }
}
class LBDetail: Mappable {
    var cardTypeID : Int?
    var cardInfo: LBBaseCardInfo?

    required init?(map: Map) {

    }

    func mapping(map: Map)
    {
        cardInfo <- map["cardInfo"]
    }
}
class LBBaseCardInfo: Mappable {

    var text: String?
    var media: LBMedia?

    required init?(map: Map) {

    }

    func mapping(map: Map) {
        text <- map["text"]
        media <- map["media"]
    }
}
class CardType1: LBBaseCardInfo {

    var background, userName : String?

    required init?(map: Map) {
        super.init(map: map)
    }

    override func mapping(map: Map) {
        super.mapping(map: map)
        background <- map["background"]
        userName <- map["userName"]
    }
}
class CardType2: LBBaseCardInfo {

    required init?(map: Map) {
        super.init(map: map)
    }

    override func mapping(map: Map) {
        super.mapping(map: map)
    }
}
class LBMedia: Mappable {

    var mediaURL: String?
    var mediaType: String?
    var mediaThumbURL: String?

    required init?(map: Map) {

    }

    func mapping(map: Map) {
        mediaURL <- map["mediaUrl"]
        mediaType <- map["mediaType"]
        mediaThumbURL <- map["mediaThumbUrl"]
    }
}

Пожалуйста, помогите мне разобратьсяэто рамки.

Ответы [ 2 ]

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

Я знаю, что это не отвечает на вопрос буквально, но это нативное решение с использованием Decodable.

Декодирует массив для ключа data в перечисление со связанными значениями.Это обрабатывает различные типы очень гладко.

В перечислении cardTypeId сначала декодируется, а в переключателе cardInfo декодируется в зависимости от идентификатора типа в соответствующую структуру.

struct Response : Decodable {
    let code : Int
    let status : String
    let data : [CardData]
}

enum CardData  {
    case user(UserData), image(ImageData), unknown
}

extension CardData: Decodable {
    private enum CodingKeys: String, CodingKey {
        case cardTypeId
        case cardInfo
    }
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let type = try container.decode(Int.self, forKey: .cardTypeId)
        switch type {
        case 1:
            let info = try container.decode(UserData.self, forKey: .cardInfo)
            self = .user(info)
        case 4:
            let info = try container.decode(ImageData.self, forKey: .cardInfo)
            self = .image(info)
        default:
            self = .unknown
        }
    }
}

struct UserData : Decodable {
    let text, userName, background : String
    let media : Media
}

struct ImageData : Decodable {
    let text : String
    let media : Media
}

struct Media : Decodable {
    let mediaUrl, mediaType, mediaThumbUrl : String
}

let jsonString = """
{
  "code": 200,
  "status": "success",
  "data": [
    {
      "cardTypeId": 1,
      "cardInfo": {
        "background": "#4267b2",
        "userName": "abkur_rt",
        "text": "Hello Video",
        "media": {
          "mediaUrl": "",
          "mediaType": "image",
          "mediaThumbUrl": ""
        }
      }
    },
    {
      "cardTypeId": 4,
      "cardInfo": {
        "text": "Image and text",
        "media": {
          "mediaUrl": "",
          "mediaType": "image",
          "mediaThumbUrl": ""
        }
      }
    }
  ]
}
"""

let data = Data(jsonString.utf8)

do {
    let result = try JSONDecoder().decode(Response.self, from: data)
    let cardData = result.data
    for item in cardData {
        switch item {
        case .user(let userData) : print(userData)
        case .image(let imageData) : print(imageData)
        case .unknown: print("unknown")
        }
    }
} catch {
    print(error)
}
0 голосов
/ 20 февраля 2019

Необходимо создать следующим образом.

1) BaseClass:

struct BaseClass : Mappable {
    var code : Int?
    var status : String?
    var data : [CardData]?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {

        code <- map["code"]
        status <- map["status"]
        data <- map["data"]
    }
}

2) CardData:

struct CardData : Mappable {
    var cardTypeId : Int?
    var cardInfo : CardInfo?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {

        cardTypeId <- map["cardTypeId"]
        cardInfo <- map["cardInfo"]
    }
}

3) Носитель:

struct Media : Mappable {
    var mediaUrl : String?
    var mediaType : String?
    var mediaThumbUrl : String?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {

        mediaUrl <- map["mediaUrl"]
        mediaType <- map["mediaType"]
        mediaThumbUrl <- map["mediaThumbUrl"]
    }
}

4) CardInfo:

struct CardInfo : Mappable {
    var background : String?
    var userName : String?
    var text : String?
    var media : Media?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {

        background <- map["background"]
        userName <- map["userName"]
        text <- map["text"]
        media <- map["media"]
    }
}

Я создал следующую структуру Mappable на основена вашем JSON.Если ваш json не содержит ключей, он будет анализировать json со значением nil.

Для вашего CardInfo я установил var text : String?, что означает, что если этот ключ недоступен, jsonбыть разобран, используя ноль.Поэтому, когда вы используете это, вы должны проверить не ноль перед развертыванием.

Надеюсь, это поможет вам.

...