我有一个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 how to map different object based on 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"]
}
}
请帮助我了解该框架。
答案 0 :(得分:0)
您需要按以下方式创建。
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"]
}
}
我已经基于您的json创建了以下Mappable结构。如果您的json不包含任何键,则它将使用nil值解析json。
我为您的CardInfo
设置了var text : String?
,这意味着,如果没有可用的密钥,则将使用nil解析json。因此,在使用此功能时,必须要求在展开前检查是否为nil。
我希望这会对您有所帮助。
答案 1 :(得分:0)
我知道它不能从字面上回答这个问题,但这是使用Decodable
的 native 解决方案。
它将键data
的数组解码为具有关联值的枚举。这可以非常平滑地处理不同类型。
在枚举中,cardTypeId
首先被解码,而在交换机cardInfo
中,根据类型ID被解码为相应的结构。
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)
}