Objectmapper: Wie füge ich Bedingungen in die Mapping-Methode ein?

Erstellt am 5. Okt. 2016  ·  4Kommentare  ·  Quelle: tristanhimmelman/ObjectMapper

Ich versuche, eine StreetAddress-Struktur aus der Google Map Place API zu implementieren, aber ich weiß nicht, wie es möglich ist, bei der Zuordnungsmethode flexibel zu sein. Ich habe in der aktuellen Dokumentation nichts dazu gefunden.

In meiner Struktur habe ich beispielsweise eine Hausnummer und eine Routeneigenschaft.
Hier ist ein Beispiel für eine JSON-Antwort von der Google API:

"address_components": [
{
"langer_name": " 36 ",
"kurzname": "36",
"Typen": [
"Hausnummer"
]
},
{
"long_name": " Rue de Dunkerque ",
"short_name": "Rue de Dunkerque",
"Typen": [
"Route"
]
},

Ich habe keine Möglichkeit gesehen, Wachbedingungen zu haben, etwa so:

guard let components = map["result.address_components"] as? [[String:Any]] else {
Rückkehr
}
// Sonstiges...

Dann könnte ich eine Möglichkeit finden, diese Informationen manuell abzurufen, aber dieser Anfang des Beispielcodes funktioniert natürlich nicht.

Braucht man dafür eine Transform oder gibt es einen anderen Weg?

Hilfreichster Kommentar

Ok das dachte ich mir, danke für diese saubere Lösung mann, sehr hilfreich !

Alle 4 Kommentare

Ich bin mir nicht sicher, was Sie vorhaben. Wenn Sie möchten...

  1. Lassen Sie den Initialisierer fehlschlagen, wenn im JSON kein result.address_components .

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

  1. Verwenden Sie stattdessen den Standardwert, wenn im JSON kein result.address_components .

=> Möglicherweise müssen Sie Transform . Siehe meine Antwort in ähnlicher Frage: #606

Tatsächlich enthält result.address_components ein Array, in dem ich verschiedene Werte abrufen möchte. Entschuldigung, dass das JSON-Beispiel in meinem ersten Beitrag schlecht formatiert ist.

Ich habe diese beiden Eigenschaften clientseitig:

var route: Zeichenfolge?
var streetNumber: String?

Diese beiden Werte sind im Array address_components vorhanden und hängen von der Eigenschaft "type" in jedem Objekt dieses Arrays ab. Ich bräuchte also Bedingungen, um sie den entsprechenden Eigenschaften zuzuordnen

Route sollte mit Wert abgebildet werden: Rue de Dunkerque & streetNumber sollte 36 . betragen

Oh, ich habe es. In diesem Fall sollten Sie Ihre eigenen Transform . Ich würde so machen:

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)
  }
}
Tipp: Verwenden Sie 3 Backticks (`), um einen Codeblock im Markdown zu erstellen.

func doSomething() {
}
func doSomething() {
}
Oder Sie können `
`-Tag, wenn Sie irgendwo einen fetten Text machen möchten.

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

Ok das dachte ich mir, danke für diese saubere Lösung mann, sehr hilfreich !

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen