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

标签 swift objectmapper rxalamofire

我正在尝试使用 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 和 Single Structure 对象的嵌套集合创建了 StructuresObject。现在我想将图 block 映射到嵌套在 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],其中键是字典键,TileStructure 是包含“布局”和“类型”属性的可映射对象。

预先感谢您的帮助:)

编辑!!!

我尝试了 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)
    }
}

我认为问题可能出在编码上,这就是造成那些转义“\”的原因,导致 key 不匹配。

最佳答案

这里使用具有动态键的 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/

关于swift - ObjectMapper - 将 JSON 字典映射为嵌套对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55128301/

相关文章:

swift - 如何在 SwiftUI 中的堆栈上设置背景颜色

ios - Swift 中的 CGSize sizeWithAttributes

ios - Swift 私有(private)访问控制导致问题

java - 将 Instant.ofEpochSecond() 对象格式反序列化为 Instant?

ios - swift 对象映射器 : How to parse array inside of an array

RxAlamofire - 如何获得错误响应?

swift - 使用 RxSwift 将 Alamofire 请求绑定(bind)到 TableView

swift - 如何将 SCNNode 移动到 ARCamera 正下方?

java - 使用 Jackson Object Mapper 将 Map 映射到 DTO 对象

ios - RxAlamofire扩展程序可在一处处理错误