ios - 从 json 中提取问题

标签 ios json swift struct here-api

我在这里经历了很多话题并尝试了不同的选择,但我似乎总是做错事.. 我设法正确获取 JSON,但我似乎无法解析我想要的部分。我在 developer.here.com 上使用反向地理编码请求

我已经尝试创建不同的结构和子结构,但似乎没有任何效果。我很感激任何帮助,因为我已经花了几个小时试图解决这个问题......

(p.s 我是 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

最佳答案

错误

keyNotFound(CodingKeys(stringValue: "Label", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"Label\", intValue: nil) (\"Label\").", underlyingError: nil))"

很清楚。这可能意味着

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

您必须始终解码 JSON 的根对象,并通过访问属性获得更深的层次。使用代码完成,它会帮助你。

关于ios - 从 json 中提取问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55530247/

相关文章:

ios - Swift 正则表达式匹配 unicode

ios - Flutter ios 设备不会从 FCM 通知触发 onMessage。实现 APN 时 Sendtodevice 失败

ios - 为什么需要在公共(public)访问控制 viewController 中重写 viewDidLoad 之前设置 public

ios - 在 Swift 中找不到 Double 类型的初始值设定项

android - 是否可以在 iOS 和/或 Android 上通过 WebView 分层其他 Xamarin.Forms 控件?

android - 如果我显示一个触发电话调用的按钮,是否可以向用户隐藏电话号码?

javascript - Jquery:使用唯一键名称迭代嵌套 JSON

javascript - 如何在 JavaScript 中同时检查最小值和最大值?

java - 转换为 JSON 字符串时扩展类中的数据丢失

ios - 查看 Swift 字符串是否包含表情符号