Objectmapper: 如何在映射方法中放置条件?

创建于 2016-10-05  ·  4评论  ·  资料来源: tristanhimmelman/ObjectMapper

我尝试从 Google Map place API 实现 StreetAddress 结构,但不知道如何灵活地映射方法,我在当前文档中没有看到与此相关的任何内容。

例如,在我的结构中,我有一个街道号码和路线属性。
以下是来自 google API 的 JSON 响应示例:

“地址组件”:[
{
"long_name": " 36 ",
"short_name": "36",
“类型”:[
“街道号码”
]
},
{
"long_name": "敦刻尔克街",
"short_name": "敦刻尔克街",
“类型”:[
“路线”
]
},

我没有看到有保护条件的方法,如下所示:

guard let components = map["result.address_components"] as? [[字符串:任何]] 其他 {
返回
}
// 其他...

然后我可以找到一种方法来手动检索这些信息,但当然,示例代码的开头不起作用。

为此需要转换还是有另一种方法?

最有用的评论

好的,这就是我的想法,感谢这个干净的解决方案人,非常有用!

所有4条评论

我不确定你打算做什么。 如果你愿意...

  1. 当 JSON 中没有result.address_components时,使初始化程序失败。

=> 见https://github.com/Hearst-DD/ObjectMapper#init_ -map-map

  1. 当 JSON 中没有result.address_components时,请改用默认值。

=> 您可能需要使用Transform 。 请参阅我在类似问题中的回答:#606

实际上没有 result.address_components 包含一个数组,我想在其中检索不同的值。 抱歉,JSON 示例在我的第一篇文章中格式错误。

我在客户端有这两个属性:

无功路线:字符串?
var streetNumber:字符串?

这两个值存在于 address_components 数组中,并取决于该数组的每个对象中的属性“类型”。 所以我需要条件将它们映射到相应的属性

路线应该用值映射: Rue de Dunkerque & streetNumber 应该等于36

哦,我明白了。 在这种情况下,您应该使用自己的Transform 。 我会这样做:

struct AddressComponent {
  var route: String?
  var streetNumber: String?
}

let addressComponentRouteTransform = TransformOf<[[String: Any]], AddressComponent>(
  // Input:
  //     [
  //       {
  //         "long_name": "36",
  //         "short_name": "36",
  //         "types": [
  //           "street_number"
  //         ]
  //       },
  //       {
  //         "long_name": "Rue de Dunkerque",
  //         "short_name": "Rue de Dunkerque",
  //         "types": [
  //           "route"
  //         ]
  //       }
  //     ]
  //
  // Output:
  //     AddressComponent(route: "36", streetName: "Rue de Dunkerque")
  fromJSON: { (componentDicts: [[String: Any]]?) -> AddressComponent?
    let route = componentDicts?.lazy
      .filter {
        guard let types = $0["types"] as? [String] else { return false }
        return types.contains("route")
      }
      .flatMap {
        $0["long_name"] as? String
      }
    let streetNumber = componentDicts?.lazy
      .filter {
        guard let types = $0["types"] as? [String] else { return false }
        return types.contains("street_number")
      }
      .flatMap {
        $0["long_name"] as? String
      }
  },

  // Input:
  //     AddressComponent(route: "36", streetName: "Rue de Dunkerque")
  //
  // Output:
  //     [
  //       {
  //         "long_name": "36",
  //         "short_name": "36",
  //         "types": [
  //           "street_number"
  //         ]
  //       },
  //       {
  //         "long_name": "Rue de Dunkerque",
  //         "short_name": "Rue de Dunkerque",
  //         "types": [
  //           "route"
  //         ]
  //       }
  //     ]
  toJSON: { (component: AddressComponent?) -> [[String: Any]]?
    var componentDicts: [[String: Any]] = []
    if let route = component?.route {
      componentDicts.append([
        "long_name": route,
        "short_name": route,
        "types": [
          "route",
        ],
      ])
    }
    if let streetNumber = component?.streetNumber {
      componentDicts.append([
        "long_name": streetNumber,
        "short_name": streetNumber,
        "types": [
          "street_number",
        ],
      ])
    }
    return componentDicts
  }
)

struct Venue {
  var address: AddressComponent

  mutating func mapping(map: Map) {
    self.address <- (map["address_components"], addressComponentRouteTransform)
  }
}
提示:使用 3 个反引号(`)在 Markdown 中制作代码块。

func doSomething() {
}
func doSomething() {
}
或者你可以使用`
` 标签,如果你想在某处加粗文本。

<pre>
func <strong>doSomething</strong>() {
}
</pre>
 func doSomething () {
 }

好的,这就是我的想法,感谢这个干净的解决方案人,非常有用!

此页面是否有帮助?
0 / 5 - 0 等级