在 swift 中解码 [string:any] 的 JSON 字典时出错



我正在尝试解码一个名为属性的字典,该字典具有 2 个键值对,具有不同类型的数据,字符串和布尔值。

{
"type": "FeatureCollection",
"query": [
"loreto"
],
"features": [
{
"id": "poi.738734375380",
"type": "Feature",
"place_type": [
"poi"
],
"relevance": 1,
"properties": {
"wikidata": "Q1932928",
"landmark": true,
"category": "airport",
"maki": "airport"
},
"text": "Aeropuerto Internacional de Loreto",
"place_name": "Aeropuerto Internacional de Loreto, Loreto, Baja California Sur 23889, Mexico",
"matching_text": "Loreto International Airport",
"matching_place_name": "Loreto International Airport, Loreto, Baja California Sur 23889, Mexico",
"center": [
-111.350714,
25.990895
],
"geometry": {
"coordinates": [
-111.350714,
25.990895
],
"type": "Point"
},
"context": [
{
"id": "postcode.18084443266252890",
"text": "23889"
},
{
"id": "place.14237343392099110",
"wikidata": null,
"text": "Loreto"
},
{
"id": "region.4595447518930340",
"short_code": "MX-BCS",
"wikidata": "Q46508",
"text": "Baja California Sur"
},
{
"id": "country.1891876083773450",
"short_code": "mx",
"wikidata": "Q96",
"text": "Mexico"
}
]
},
{
"id": "region.7294174250099110",
"type": "Feature",
"place_type": [
"region"
],
"relevance": 1,
"properties": {
"short_code": "PE-LOR",
"wikidata": "Q200938"
},
"text": "Loreto",
"place_name": "Loreto, Peru",
"bbox": [
-77.810369,
-8.645157,
-69.962572,
-0.029093
],
"center": [
-74.32,
-4
],
"geometry": {
"type": "Point",
"coordinates": [
-74.32,
-4
]
},
"context": [
{
"id": "country.8104362620964510",
"short_code": "pe",
"wikidata": "Q419",
"text": "Peru"
}
]
},
{
"id": "place.13763862540099110",
"type": "Feature",
"place_type": [
"place"
],
"relevance": 1,
"properties": {
"wikidata": "Q124110"
},
"text": "Loreto",
"place_name": "Loreto, Ancona, Italy",
"bbox": [
13.579312,
43.416918,
13.658326,
43.45622
],
"center": [
13.60743,
43.4403
],
"geometry": {
"type": "Point",
"coordinates": [
13.60743,
43.4403
]
},
"context": [
{
"id": "region.9523893847640810",
"short_code": "IT-AN",
"wikidata": "Q16114",
"text": "Ancona"
},
{
"id": "country.4747984886519910",
"short_code": "it",
"wikidata": "Q38",
"text": "Italy"
}
]
},
{
"id": "poi.2568390505832",
"type": "Feature",
"place_type": [
"poi"
],
"relevance": 1,
"properties": {
"landmark": true,
"address": "Calle 5, La Urbina",
"category": "italian restaurant, italian food, restaurant"
},
"text": "Loreto's",
"place_name": "Loreto's, Calle 5, La Urbina, Sucre, Miranda, Venezuela",
"center": [
-66.808422,
10.49214
],
"geometry": {
"coordinates": [
-66.808422,
10.49214
],
"type": "Point"
},
"context": [
{
"id": "place.13896838717891910",
"wikidata": "Q400079",
"text": "Sucre"
},
{
"id": "region.2525680865649430",
"short_code": "VE-M",
"wikidata": "Q191174",
"text": "Miranda"
},
{
"id": "country.5958724522570350",
"short_code": "ve",
"wikidata": "Q717",
"text": "Venezuela"
}
]
},
{
"id": "poi.2439541497917",
"type": "Feature",
"place_type": [
"poi"
],
"relevance": 1,
"properties": {
"landmark": true,
"address": "Corredera baja de San Pablo, 6",
"category": "spanish restaurant, spanish food, restaurant"
},
"text": "Loreto Coffee-Bar",
"place_name": "Loreto Coffee-Bar, Corredera baja de San Pablo, 6, Madrid, Madrid 28004, Spain",
"center": [
-3.704493,
40.421894
],
"geometry": {
"coordinates": [
-3.704493,
40.421894
],
"type": "Point"
},
"context": [
{
"id": "locality.5946271622443140",
"wikidata": "Q10387767",
"text": "Universidad"
},
{
"id": "postcode.9832348953129320",
"text": "28004"
},
{
"id": "place.10692955307562040",
"wikidata": "Q2807",
"text": "Madrid"
},
{
"id": "region.13206054317562040",
"short_code": null,
"wikidata": "Q2807",
"text": "Madrid"
},
{
"id": "country.8849824479570100",
"short_code": "es",
"wikidata": "Q29",
"text": "Spain"
}
]
}
],
"attribution": "NOTICE: © 2019 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained. POI(s) provided by Foursquare."
}

当我使用 JSONDecoder 时会发生此错误: "预计解码字符串,但找到了一个数字。">

在 Swift 中可解码不允许使用 [字符串:任何] 我已经尝试过像数组一样解码,但是不,是字典。

struct SearchResult:Decodable{
let type:String
let features:[Place]
}
struct Place:Decodable {
let place_name:String
let properties:[String:String]
let center:[Double]
}

我该怎么办?

问题是这一行:

let properties:[String:String]

在这里你说properties是一本字典。这还不够好。当然,在JSON中它是一个字典,但是要使用JSONDecoder解码字典,您需要一个与字典匹配的进一步嵌套结构。我们称之为属性。所以你会说

let properties:Properties

然后,您将定义一个可解码的属性结构。

但是,您有一个问题:properties字典并不都具有相同的键集。每次都有,有些不在。若要解决此问题,请在定义属性结构时使用 Optionals:

struct SearchResult:Decodable{
let type:String
let features:[Place]
}
struct Place:Decodable {
let place_name:String
let properties:Properties
let center:[Double]
}
struct Properties:Decodable {
let landmark : Bool?
let address : String?
let category : String?
let wikidata : String?
let short_code : String?
let maki : String?
}

这似乎可以成功解码您实际显示的 JSON。我明白这个:

搜索结果(类型: "FeatureCollection", 特征: [地点(place_name: "洛雷托国际机场, 洛雷托, 下加利福尼亚州南 23889, 墨西哥", 属性: 属性(地标: 可选(true), 地址: 无, 类别: 可选("机场"), 维基数据: 可选("Q1932928"), short_code: 无,

maki: 可选("机场")), 中心: [-111.350714, 25.9908949999999998]), 地点(place_name: "洛雷托, 秘鲁", 属性: 属性(地标: 无, 地址: 无, 类别: 无, 维基数据: 可选("Q200938"), short_code: 可选("PE-LOR"), 卷: 无), 中心: [-74.319999999999993, -4.0]), 地点(place_name: "洛雷托, 安科纳, 意大利", 属性: 属性(地标: 无, 地址: 无, 类别: 无, 维基数据: 可选("Q124110"), short_code: 无, 卷: 无), 中心: [13.607430000000001, 43.4403000000000001]), 地点(place_name: "洛雷托, Calle 5, La Urbina, Sucre, 米兰达, 委内瑞拉", 属性: 属性(地标: 可选(true), 地址: 可选("Calle 5, La Urbina"), 类别: 可选("意大利餐厅, 意大利菜, 餐厅"), 维基数据: 无, short_code: 无, maki: nil), 中心: [-66.8084219999999993, 10.4921399999999999]), 地点(place_name: "Loreto Coffee-Bar, Corredera baja de San Pablo, 6, 马德里, 马德里 28004, 西班牙", 属性: 属性(地标: 可选(true), 地址: 可选("Corredera baja de San Pablo, 6"), 类别: 可选("西班牙餐厅, 西班牙美食, 餐厅"), 维基数据: 无, short_code: 无, 牧: 无), 中心: [-3.70449299999999998, 40.4218940000000002])])

如果我错过了任何可能的键,只需以相同的方式添加它们。使用mapbox api检查是否有任何其他可能性。

相关内容

  • 没有找到相关文章

最新更新