I try to implement a StreetAddress struct from Google Map place API but dunno how it's possible to be flexible in mapping method, I didn't see anything related to this in current documentation.
For example in my struct, I have a street number and route property.
Here is a sample of JSON response from google API:
"address_components": [
{
"long_name": "36",
"short_name": "36",
"types": [
"street_number"
]
},
{
"long_name": "Rue de Dunkerque",
"short_name": "Rue de Dunkerque",
"types": [
"route"
]
},
I didn't see a way to have guard conditions, something like this:
guard let components = map["result.address_components"] as? [[String:Any]] else {
return
}
// other...
Then I could find a way to retrieve manually these informations but of course, this beginning of sample code doesn't work.
Is a Transform needed for this or there is another way ?
I'm not sure what you intend to do. If you'd like to...
result.address_components
in the JSON.=> See https://github.com/Hearst-DD/ObjectMapper#init_-map-map
result.address_components
in the JSON.=> You might need to use Transform
. See my answer in similar question: #606
No in fact result.address_components contains an array where I want to retrieve different values. Sorry the JSON sample is badly formatted in my first post.
I have these two properties client-side:
var route: String?
var streetNumber: String?
These two values are presents in address_components array, and depend on the property "type" in each objects of this array. So I'd need conditions to map them to corresponding properties
route should be mapped with value: Rue de Dunkerque & streetNumber should equal to 36
Oh, I got it. In this case you should use your own Transform
. I would do like this:
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)
}
}
Tip: Use 3 backticks(`) to make a code block in markdown.
func doSomething() { }
func doSomething() {
}
Or you can use `` tag if you want to make a bold text somewhere.<pre> func <strong>doSomething</strong>() { } </pre>
func doSomething() { }
Ok that's what I thought, thanks for this clean solution man, very useful !
Most helpful comment
Ok that's what I thought, thanks for this clean solution man, very useful !