ObjectMapper - 将JSON字典映射为嵌套对象

问题描述 投票:0回答:1

我正在尝试使用ObjectMapper来使用JSON响应。到目前为止,我的回答如下:

{
  "paramsStructure": [
    {
      "tiles": {
        "0": {
          "layout": {
            "column": 0,
            "colSpan": "1",
            "rowSpan": "1",
            "row": 0
          },
          "type": "2"
        },
        "1": {
          "layout": {
            "column": 1,
            "colSpan": "1",
            "rowSpan": "1",
            "row": 0
          },
          "type": "2"
        }
      },
      "title": "...",
      "rowCount": "4",
      "colCount": "2",
      "key": "...",
      "icon": "..."
    }
  ]
}

到目前为止,我已经为整个paramsStructure创建了StructuresObject,并为单个结构对象创建了嵌套集合。现在我想将tile映射到嵌套在Structure对象中的TileStructure对象集合,如下所示。

class SingleStructure : Mappable{

    var columns: Int = 0
    var title: String = ""
    var key: String = ""
    var icon: String = ""
    var tilesStructure : [Int: TileStructure]?

    required init?(map: Map) {

    }

    func mapping(map: Map) {
        title <- map["title"]
        key <- map["key"]
        icon <- map["icon"]
        columns <- (map["colCount"], TransformOf<Int, String>(
            fromJSON: {item in return Int(item!)},
            toJSON: {_ in return "$0"}))


        //need here parsing of tilesStructure
     }
}

我主要需要将这个JSON tiles字典映射到[Int:TileStructure],其中key是字典键,TileStructure是包含“layout”和“type”属性的可映射对象。

预先感谢您的帮助 :)

编辑!!!

我尝试了denis_lor方法但是当我从RxAlamofire运行解析数据时,我得到以下异常:

keyNotFound(CodingKeys(stringValue: "tiles", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"tiles\", intValue: nil) (\"tiles\").", underlyingError: nil))

这就是我打电话请求的方式

 return RxAlamofire.requestData(.get, GlobalSettings.GET_DEVICE_MAIN_STRUCTURE, parameters: parameters, headers: headers)
        .debug()

        .mapObject(type: ParamsStructure.self)

这就是我的对象映射器:

extension ObservableType {

public func mapObject<T: Codable>(type: T.Type) -> Observable<T> {
    return flatMap { data -> Observable<T> in
        let responseTuple = data as? (HTTPURLResponse, Data)

        guard let jsonData = responseTuple?.1 else {
            throw NSError(
                domain: "",
                code: -1,
                userInfo: [NSLocalizedDescriptionKey: "Could not decode object"]
            )
        }

        let decoder = JSONDecoder()

        let object = try decoder.decode(T.self, from: jsonData)

        return Observable.just(object)
    }
}

}

我认为这个问题可能是编码,这就是创造那些逃避“\”的因素导致密钥不匹配的原因。

swift objectmapper rxalamofire
1个回答
1
投票

这里使用json结构的关键是使用动态键,就像使用Dictionary一样使用[String:Tile]

你可以试试新的Swift4's Codable

import Foundation

public struct ResultParamsStructure: Codable {
    public var paramsStructure: [ParamsStructure] = []

    enum CodingKeys: String, CodingKey {
        case paramsStructure = "paramsStructure"
    }
}

public struct ParamsStructure: Codable {
    public var tiles: [String:Tile] = [:]
    public var title: String = ""
    public var rowCount: String = ""
    public var colCount: String = ""
    public var key: String = ""
    public var icon: String = ""

    enum CodingKeys: String, CodingKey {
        case tiles = "tiles"
        case title = "title"
        case rowCount = "rowCount"
        case colCount = "colCount"
        case key = "key"
        case icon = "icon"
    }
}

public struct Tile: Codable {
    public var layout: Layout?
    public var type: String = ""

    enum CodingKeys: String, CodingKey {
        case layout = "layout"
        case type = "type"
    }
}

public struct Layout: Codable {
    public var column: Int = 0
    public var colSpan: String = ""
    public var rowSpan: String = ""
    public var row: Int = 0

    enum CodingKeys: String, CodingKey {
        case column = "column"
        case colSpan = "colSpan"
        case rowSpan = "rowSpan"
        case row = "row"
    }
}

let jsonString = """
{
  "paramsStructure": [
    {
      "tiles": {
        "0": {
          "layout": {
            "column": 0,
            "colSpan": "1",
            "rowSpan": "1",
            "row": 0
          },
          "type": "2"
        },
        "1": {
          "layout": {
            "column": 1,
            "colSpan": "1",
            "rowSpan": "1",
            "row": 0
          },
          "type": "2"
        }
      },
      "title": "...",
      "rowCount": "4",
      "colCount": "2",
      "key": "...",
      "icon": "..."
    }
  ]
}
"""

let json = jsonString.data(using: .utf8)!

let resultParamsStructure = try? JSONDecoder().decode(ResultParamsStructure.self, from: json)

print(resultParamsStructure?.paramsStructure[0].tiles.keys)
print(resultParamsStructure?.paramsStructure[0].tiles["1"]?.layout?.colSpan)
//# Optional(Dictionary.Keys(["0", "1"]))
//# Optional("1")

你可以在这里尝试上面的代码:http://online.swiftplayground.run/

© www.soinside.com 2019 - 2024. All rights reserved.