Возникли проблемы с извлечением из JSON - PullRequest
0 голосов
/ 05 апреля 2019

Я прошел через множество потоков и пробовал разные варианты, но я, кажется, постоянно делаю что-то не так ... Мне удается правильно получить JSON, но я не могу разобрать нужные части.Я использую обратный запрос геокода на developer.here.com

Я пытался создать различные структуры и подструктуры, но ничего не помогло.Я был бы признателен за любую помощь, так как я потратил часы, пытаясь это исправить ...

(ps, я новичок в JSON), вот вам дикт, я пытался извлечь метку, которая находится под адресом, такжевот ссылка, так как я не мог заставить ее выглядеть красиво https://developer.here.com/api-explorer/rest/geocoder/reverse-geocode:

{
  "Response": {
    "MetaInfo": {
      "Timestamp": "2019-04-04T17:45:06.052+0000",
      "NextPageInformation": "2"
    },
    "View": [
      {
        "_type": "SearchResultsViewType",
        "ViewId": 0,
        "Result": [
          {
            "Relevance": 1,
            "Distance": 13.6,
            "MatchLevel": "houseNumber",
            "MatchQuality": {
              "Country": 1,
              "State": 1,
              "County": 1,
              "City": 1,
              "District": 1,
              "Street": [
                1
              ],
              "HouseNumber": 1,
              "PostalCode": 1
            },
            "MatchType": "pointAddress",
            "Location": {
              "LocationId": "NT_Opil2LPZVRLZjlWNLJQuWB_0ITN",
              "LocationType": "address",
              "DisplayPosition": {
                "Latitude": 41.88432,
                "Longitude": -87.63877
              },
              "NavigationPosition": [
                {
                  "Latitude": 41.88449,
                  "Longitude": -87.63877
                }
              ],
              "MapView": {
                "TopLeft": {
                  "Latitude": 41.8854442,
                  "Longitude": -87.64028
                },
                "BottomRight": {
                  "Latitude": 41.8831958,
                  "Longitude": -87.63726
                }
              },
              "Address": {
                "Label": "425 W Randolph St, Chicago, IL 60606, United States",
                "Country": "USA",
                "State": "IL",
                "County": "Cook",
                "City": "Chicago",
                "District": "West Loop",
                "Street": "W Randolph St",
                "HouseNumber": "425",
                "PostalCode": "60606",
                "AdditionalData": [
                  {
                    "value": "United States",
                    "key": "CountryName"
                  },
                  {
                    "value": "Illinois",
                    "key": "StateName"
                  },
                  {
                    "value": "Cook",
                    "key": "CountyName"
                  },
                  {
                    "value": "N",
                    "key": "PostalCodeType"
                  }
                ]
              },
              "MapReference": {
                "ReferenceId": "776372180",
                "MapId": "NAAM191N0",
                "MapVersion": "Q1/2019",
                "MapReleaseDate": "2019-01-28",
                "Spot": 0.52,
                "SideOfStreet": "right",
                "CountryId": "21000001",
                "StateId": "21002247",
                "CountyId": "21002623",
                "CityId": "21002647",
                "BuildingId": "9000000000002726912",
                "AddressId": "79186508",
                "RoadLinkId": "170008450"
              }
            }
          }
        ]
      }
    ]
  }
}

  struct Welcome: Codable {
    let response: Response

    enum CodingKeys: String, CodingKey {
        case response = "Response"
    }
}

struct Response: Codable {
    let metaInfo: MetaInfo
    let view: [View]

    enum CodingKeys: String, CodingKey {
        case metaInfo = "MetaInfo"
        case view = "View"
    }
}

struct MetaInfo: Codable {
    let timestamp, nextPageInformation: String

    enum CodingKeys: String, CodingKey {
        case timestamp = "Timestamp"
        case nextPageInformation = "NextPageInformation"
    }
}

struct View: Codable {
    let type: String
    let viewID: Int
    let result: [Result]

    enum CodingKeys: String, CodingKey {
        case type = "_type"
        case viewID = "ViewId"
        case result = "Result"
    }
}

struct Result: Codable {
    let relevance: Int
    let distance: Double
    let matchLevel: String
    let matchQuality: MatchQuality
    let matchType: String
    let location: Location

    enum CodingKeys: String, CodingKey {
        case relevance = "Relevance"
        case distance = "Distance"
        case matchLevel = "MatchLevel"
        case matchQuality = "MatchQuality"
        case matchType = "MatchType"
        case location = "Location"
    }
}

struct Location: Codable {
    let locationID, locationType: String
    let displayPosition: DisplayPosition
    let navigationPosition: [DisplayPosition]
    let mapView: MapView
    let address: Address
    let mapReference: MapReference

    enum CodingKeys: String, CodingKey {
        case locationID = "LocationId"
        case locationType = "LocationType"
        case displayPosition = "DisplayPosition"
        case navigationPosition = "NavigationPosition"
        case mapView = "MapView"
        case address = "Address"
        case mapReference = "MapReference"
    }
}

struct Address: Codable {
    let label, country, state, county: String
    let city, district, street, houseNumber: String
    let postalCode: String
    let additionalData: [AdditionalDatum]

    enum CodingKeys: String, CodingKey {
        case label = "Label"
        case country = "Country"
        case state = "State"
        case county = "County"
        case city = "City"
        case district = "District"
        case street = "Street"
        case houseNumber = "HouseNumber"
        case postalCode = "PostalCode"
        case additionalData = "AdditionalData"
    }
}

struct AdditionalDatum: Codable {
    let value, key: String
}

struct DisplayPosition: Codable {
    let latitude, longitude: Double

    enum CodingKeys: String, CodingKey {
        case latitude = "Latitude"
        case longitude = "Longitude"
    }
}

struct MapReference: Codable {
    let referenceID, mapID, mapVersion, mapReleaseDate: String
    let spot: Double
    let sideOfStreet, countryID, stateID, countyID: String
    let cityID, buildingID, addressID, roadLinkID: String

    enum CodingKeys: String, CodingKey {
        case referenceID = "ReferenceId"
        case mapID = "MapId"
        case mapVersion = "MapVersion"
        case mapReleaseDate = "MapReleaseDate"
        case spot = "Spot"
        case sideOfStreet = "SideOfStreet"
        case countryID = "CountryId"
        case stateID = "StateId"
        case countyID = "CountyId"
        case cityID = "CityId"
        case buildingID = "BuildingId"
        case addressID = "AddressId"
        case roadLinkID = "RoadLinkId"
    }
}

struct MapView: Codable {
    let topLeft, bottomRight: DisplayPosition

    enum CodingKeys: String, CodingKey {
        case topLeft = "TopLeft"
        case bottomRight = "BottomRight"
    }
}

struct MatchQuality: Codable {
    let country, state, county, city: Int
    let district: Int
    let street: [Int]
    let houseNumber, postalCode: Int

    enum CodingKeys: String, CodingKey {
        case country = "Country"
        case state = "State"
        case county = "County"
        case city = "City"
        case district = "District"
        case street = "Street"
        case houseNumber = "HouseNumber"
        case postalCode = "PostalCode"
    }
}


guard let jsonString = try JSONSerialization.jsonObject(with: data, options: []) as? [String:AnyObject] else {return}
            print (jsonString)//it prints the json correctly
            let address_label = try? JSONDecoder().decode(Address.self, from: data)
            print(address_label) //prints out nil
            // some more code here that catches errors

1 Ответ

2 голосов
/ 05 апреля 2019

Ошибка

keyNotFound (CodingKeys (stringValue: "Label", intValue: nil), Swift.DecodingError.Context (codingPath: [], debugDescription: "Нет значения, связанного с ключом CodingKeys (stringValue: \" Label \ ", intValue: nil) ) (\ "Метка \"). ", UnderError: nil))"

довольно ясно. Это может означать

  1. Указанный ключ не существует в JSON. Это не тот случай, когда ключ Label существует.
  2. Вы декодируете неправильную структуру. Это случай , поскольку корневым объектом является Welcome.

Вы должны всегда декодировать корневой объект JSON и получать более глубокие уровни, обращаясь к свойствам. Используйте дополнения кода, это поможет вам.

...