【问题标题】:How can I do array mapping with objectmapper?如何使用 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/

【问题讨论】:

    标签: swift objectmapper


    【解决方案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"]
            }}
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-10-25
              • 1970-01-01
              • 1970-01-01
              • 2016-12-31
              • 1970-01-01
              • 2018-03-28
              • 1970-01-01
              • 2015-11-27
              相关资源
              最近更新 更多