如何使用 objectmapper 进行数组映射?

Posted

技术标签:

【中文标题】如何使用 objectmapper 进行数组映射?【英文标题】:How can I do array mapping with objectmapper? 【发布时间】:2017-04-26 16:06:36 【问题描述】:

我有一个如下所示的响应模型:

class ResponseModel: Mappable 

    var data: T?
    var code: Int = 0

    required init?(map: Map) 

    func mapping(map: Map) 
        data <- map["data"]
        code <- map["code"]
    

如果 json-data 不是数组,它可以工作:

"code":0,"data":"id":"2","name":"XXX"

但是如果是数组就不行

"code":0,"data":["id":"2","name":"XXX","id":"3","name":"YYY"]

我的映射代码;

let apiResponse = Mapper<ResponseModel>().map(JSONObject: response.result.value)

详情; 我使用这篇文章尝试了这段代码:http://oramind.com/rest-client-in-swift-with-promises/

【问题讨论】:

【参考方案1】:

您需要使用mapArray 方法而不是map

let apiResponse = Mapper<ResponseModel>().mapArray(JSONObject: response.result.value)

【讨论】:

【参考方案2】:

我做的是这样的:

func mapping(map: Map) 
    if let _ = try? map.value("data") as [Data] 
       dataArray <- map["data"]
     else 
       data <- map["data"]
    

    code <- map["code"]

地点:

var data: T?
var dataArray: [T]?
var code: Int = 0

问题在于您需要同时检查 datadataArray 的 nil 值。

【讨论】:

【参考方案3】:

您需要将数据声明更改为数组,因为它在 JSON 中是这样的:

var data: [T]? 

【讨论】:

但数据有时对象有时是数组。两者都有办法吗? 创建两个独立的可映射类,一个用于数组,一个不用于数组。尝试映射第一个,如果失败,请尝试第二个。 此外,即使只有一个元素,API 也应该真正将对象包装在数组对象中。【参考方案4】:
let apiResponse = Mapper<ResponseModel>().mapArray(JSONObject: response.result.value)

为我工作

【讨论】:

【参考方案5】:

任何使用 SwiftyJSON 的人,如果你想直接从 JSON 中获取一个对象,而没有父类,例如,你想从中获取“数据”。你可以这样做,

if let data = response.result.value 
   let json = JSON(data)
   let dataResponse = json["data"].object
   let responseObject = Mapper<DataClassName>().mapArray(JSONObject: dataResponse)

这将返回[DataClassName]? 作为回复。

【讨论】:

【参考方案6】:

基于 Abrahanfer 的回答。我分享我的解决方案。我为 Alamofire 写了一个 BaseResult。

class BaseResult<T: Mappable> : Mappable 

var Result : Bool = false
var Error : ErrorResult?
var Index : Int = 0
var Size : Int = 0
var Count : Int = 0
var Data : T?
var DataArray: [T]?

required init?(map: Map)



func mapping(map: Map) 
    Result  <- map["Result"]
    Error <- map["Error"]
    Index <- map["Index"]
    Size <- map["Size"]
    Count <- map["Count"]

    if let _ = try? map.value("Data") as [T] 
       DataArray <- map["Data"]
     else 
       Data <- map["Data"]
    

Alamofire 的用法:

WebService.shared.request(url, params, encoding: URLEncoding.default, success:  (response : BaseResult<TypeData>) in

            if let arr = response.DataArray
            
                for year in arr
                
                   self.years.append(year)
                
            
        , failure: 

        )

请求方法是:

 func request<T: Mappable>(_ url: String,_ parameters: [String : Any] = [:], _ method: HTTPMethod = .post,_ httpHeaders: HTTPHeaders? = nil, encoding: ParameterEncoding = JSONEncoding.default, success: @escaping (T) -> Void, failure: @escaping () -> () ) 

    AF.request(newUrl, method:method, parameters:parameters, encoding:encoding, headers: httpHeaders)

    .responseJSON  response in

        if let res = response.value 
            let json = res as! [String: Any]
            if let object = Mapper<T>().map(JSON: json) 
                success(object)
                return
            
        else if let _ = response.error 
            failure()
        
    

TypeData 类是:

class TypeData : Mappable

var Id : String = ""
var Title: String =  ""

required init(map: Map)



func mapping(map: Map) 
    Id  <- map["ID"]
    Title  <- map["YEAR"]

【讨论】:

以上是关于如何使用 objectmapper 进行数组映射?的主要内容,如果未能解决你的问题,请参考以下文章

ObjectMapper 如何基于 JSON 映射不同的对象

ObjectMapper 和具有唯一键的数组

如何将可映射数组转换为 JSON?

如何使用 ObjectMapper 将枚举的 rawValue 分配给变量?

Swift - 嵌套对象的映射 (Objectmapper)

Retrofit 或 Jackson ObjectMapper 将“aId”属性映射为小写“aid”