在Swift中使用ObjectMapper中的TranfsformType映射类对象 [英] Mapping class object using TranfsformType in ObjectMapper in Swift
问题描述
我有一个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屋!