我正在尝试解码一个名为properties的字典,该字典具有2个键值对,具有不同类型的数据,即String和Boolean。
{
"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时发生此错误: “希望对String进行解码,但是找到了一个数字。”
Swift中的Decodable不允许使用[String:Any] 我已经尝试过像数组一样解码,但是nop是字典。
struct SearchResult:Decodable{
let type:String
let features:[Place]
}
struct Place:Decodable {
let place_name:String
let properties:[String:String]
let center:[Double]
}
我该怎么办?
答案 0 :(得分:1)
问题是这一行:
let properties:[String:String]
在这里您说properties
是一本字典。这还不够好。当然,在JSON中它是一个字典,但是要使用JSONDecoder解码字典,您需要另一个与字典匹配的嵌套结构。我们称之为属性。所以你会说
let properties:Properties
然后您将定义一个可解码的Properties结构。
但是,您遇到了一个问题:properties
词典并不都具有相同的键集。每次都有一些存在,有些则没有。要解决此问题,请在定义“属性”结构时使用“可选”:
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。我明白了:
SearchResult(类型:“ FeatureCollection”,功能:[Place(place_name:“墨西哥洛洛托国际机场,洛雷托,墨西哥下加利福尼亚州苏里23889”,属性:属性(具有里程碑意义:可选(true),地址:无,类别:可选(“机场”),维基数据:可选(“ Q1932928”),短代码:无,马基:可选(“机场”)),中心:[-111.350714,25.990894999999998]),地点(地点名称:“洛雷托,秘鲁” ,属性:属性(地标:无,地址:无,类别:无,wikidata:可选(“ Q200938”),短代码:可选(“ PE-LOR”),maki:无),中心:[-74.319999999999993,-4.0 ]),地点(地点名称:“洛雷托,安科纳,意大利”,属性:属性(地标:无,地址:无,类别:无,Wikidata:可选(“ Q124110”),短代码:无,马基:无),中心:[13.607430000000001,43.440300000000001]),地点(地名:“洛雷托\,Calle 5,La Urbina,苏克雷,米兰达,委内瑞拉”),属性:Properties(地标:Optional(true),地址:Optional(“ Calle 5, La Urbina”),类别:可选(“ italian r餐馆,意大利美食,餐厅”),维基百科数据:无,简码:无,马基:无),中心:[-66.808421999999993、10.492139999999999]),地点(地名:“洛雷托咖啡吧,圣巴勃罗·德·巴雷德·德·巴勃罗,6岁,马德里,马德里28004,西班牙”,属性:属性(地标:Optional(true),地址:Optional(“ Corredera baja de San Pablo,6”),类别:Optional(“西班牙餐厅,西班牙美食,餐厅”),wikidata :nil,简码:nil,maki:nil),中心:[-3.7044929999999998,40.421894000000002])])
如果我错过了任何可能的键,只需以相同的方式添加它们。请使用mapbox api检查是否还有其他可能性。