从json提取问题

时间:2019-04-05 07:25:26

标签: ios json swift struct here-api

我在这里经历了很多线程,并尝试了不同的选择,但是我似乎一直在做错事。 我设法正确获取JSON,但似乎无法解析所需的部分。我在developer.here.com

上使用反向地理编码请求

我尝试创建不同的结构和子结构,但似乎没有任何效果。我将不胜感激,因为我已经花了很多时间尝试解决此问题...

(p.s是JSON的新功能) 这是字典,我一直在尝试提取地址下的thats标签,因为我无法使它看起来不错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 个答案:

答案 0 :(得分:2)

错误

  

keyNotFound(CodingKeys(stringValue:“ Label”,intValue:nil),Swift.DecodingError.Context(codingPath:[],debugDescription:“没有与键CodingKeys(stringValue:\” Label \“,intValue:nil相关联的值) )(\“ Label \”)。“,underlyingError:nil))”

很清楚。可能是

  1. 提到的密钥在JSON中不存在。情况并非如此,因为密钥Label确实存在。
  2. 您正在解码错误的结构。 是这种情况,因为根对象是Welcome

您必须始终解码JSON的根对象,并通过访问属性获得更深层次的信息。使用代码补全功能,对您有帮助。