在Swift中使用ObjectMapper中的TranfsformType映射类对象 [英] Mapping class object using TranfsformType in ObjectMapper in Swift

查看:267
本文介绍了在Swift中使用ObjectMapper中的TranfsformType映射类对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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中根据cardTypeId我得到cardInfo,所以我制作了引用此链接的类

To Parse this i used ObjectMapper(https://github.com/tristanhimmelman/ObjectMapper) My query is that in my JSON i get cardInfo depending upon the cardTypeId So I made classes referring this link ObjectMapper how to map different object based on JSON to understand how to make use of custom TransformType for classes. In the link's JSON reponse has Array but in my case if cardTypeId is 1 then there is 2 fields extra where as everything same in cardInfo. So i have made classes as below but i am not sure how will i create class inheriting 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"]
    }
}

请帮助我了解该框架.

推荐答案

我知道它不能从字面上回答问题,但这是使用Decodable native 解决方案.

I know it doesn't answer the question literally, but this is a native solution using Decodable.

它将键data的数组解码为具有关联值的枚举.这可以非常平滑地处理各种类型.

It decodes the array for key data into an enum with associated values. This handles the different types very smoothly.

首先将枚举中的cardTypeId解码,然后将根据类型ID的开关中的cardInfo解码为对应的结构.

In the enum cardTypeId is decoded first and in a switch cardInfo is decoded depending on the type ID into the corresponding struct.

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

这篇关于在Swift中使用ObjectMapper中的TranfsformType映射类对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆