使用 Codable 解析嵌套 JSON 数据问题
Posted
技术标签:
【中文标题】使用 Codable 解析嵌套 JSON 数据问题【英文标题】:Using Codable to parse nested JSON data problem 【发布时间】:2018-12-15 07:48:07 【问题描述】:*我正在尝试使用 Codable 来解析复杂的 JSON 数据。但我对"route_polyline"
field 有疑问。
问题:
CodingKeys(stringValue: "route_polyline", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "预期解码 Dictionary 但找到了一个数组。
有什么帮助吗?我想使用 Codable 而不是 JSONSerialization。
我的模特:
struct RouteFareResponse: Decodable
let status: String
let trip_cost: Trip_cost
struct Trip_cost: Decodable
let start_address: String
let end_address: String
let trip_time: Int
let trip_distance: String
let transmit_cost: Int
let cost_in_zone: Int
let outdoor_zone_cost: Int
let sub_zones_cost: Int
let perform_cost: Int
let services_cost: Int
let min_cost: Int
let discount_by_promo: Int
let result_trip_cost:Int
let trip_cost: Int
let trip_cost_with_discount: Int
let route_polyline: [Polyline]
let _debug_sub_zones_info: String//Dict
let _debug: [Debug]
struct Polyline: Decodable
var lat: Double
var long: Double
enum PolylineKeys: String, CodingKey
case route_polyline
init(from decoder: Decoder) throws
let values = try decoder.container(keyedBy: PolylineKeys.self)
var route_polyline = try values.nestedUnkeyedContainer(forKey: .route_polyline)
var longLat = try route_polyline.nestedUnkeyedContainer()
long = try longLat.decode(Double.self)
lat = try longLat.decode(Double.self)
struct Debug: Codable
let trip_distance: Int
let trip_time: Int
let zone_distance: Int
let zone_time: Int
let out_zone_distance: Int
let out_zone_time: Int
// let transmit_distance: NSNull
// let transmit_time: NSNull
let tariff_price_prefix: String
JSON 响应:
"status": "success",
"trip_cost":
"start_address": "2-й Павловский пер., 18, Москва, Россия, 115093",
"end_address": "Piața Marii Adunări Naționale, Bulevardul Ștefan cel Mare și Sfînt, Chișinău, Молдавия",
"trip_time": 934,
"trip_distance": "1,314.52",
"transmit_cost": 0,
"cost_in_zone": 0,
"outdoor_zone_cost": 0,
"sub_zones_cost": 0,
"perform_cost": 0,
"services_cost": 0,
"min_cost": 0,
"discount_by_promo": 0,
"result_trip_cost": 0,
"trip_cost": 0,
"trip_cost_with_discount": 0,
"route_polyline": [
[
55.71801,
37.62929
],
[
55.71376,
37.63317
],
[
55.71108,
37.62459
],
[
55.70636,
37.62239
],
[
55.70134,
37.608
],
[
55.7115,
37.58071
],
[
55.67312,
37.52316
],
[
55.63334,
37.44638
],
[
55.54088,
37.08855
],
[
55.51861,
36.99843
],
[
55.47076,
36.92839
],
[
55.36682,
36.75983
],
[
55.33846,
36.72214
],
[
55.32199,
36.70649
],
[
55.2975,
36.70001
],
[
55.2369,
36.68447
],
[
55.17533,
36.67373
],
[
55.07732,
36.62831
],
[
55.04849,
36.60693
],
[
55.0127,
36.54831
],
[
54.97539,
36.48667
],
[
54.92141,
36.39975
],
[
54.90194,
36.36941
],
[
54.8747,
36.35157
],
[
54.83675,
36.32096
],
[
54.77415,
36.23814
],
[
54.73767,
36.18605
],
[
54.71318,
36.16446
],
[
54.64494,
36.13463
],
[
54.62446,
36.12338
],
[
54.59645,
36.08795
],
[
54.54708,
36.01808
],
[
54.5191,
35.97127
],
[
54.47491,
35.88614
],
[
54.40394,
35.73519
],
[
54.36474,
35.62843
],
[
54.32196,
35.50525
],
[
54.24807,
35.43855
],
[
54.18797,
35.34998
],
[
54.15873,
35.29848
],
[
54.14077,
35.28455
],
[
54.09443,
35.2272
],
[
54.04353,
35.14278
],
[
53.99988,
35.08885
],
[
53.95291,
35.02331
],
[
53.89699,
34.94324
],
[
53.78786,
34.82704
],
[
53.76976,
34.81073
],
[
53.74931,
34.80781
],
[
53.71795,
34.80157
],
[
53.66801,
34.77262
],
[
53.60077,
34.7352
],
[
53.55531,
34.70988
],
[
53.4788,
34.67168
],
[
53.45724,
34.66608
],
[
53.4438,
34.67235
],
[
53.41763,
34.66852
],
[
53.38279,
34.65954
],
[
53.3233,
34.64507
],
[
53.21967,
34.61469
],
[
53.01306,
34.5253
],
[
52.94232,
34.5251
],
[
52.84383,
34.52932
],
[
52.79696,
34.53675
],
[
52.7599,
34.5311
],
[
52.71971,
34.53223
],
[
52.66035,
34.53044
],
[
52.64336,
34.51429
],
[
52.6047,
34.51525
],
[
52.43118,
34.50557
],
[
52.38021,
34.50342
],
[
52.35699,
34.49416
],
[
52.2817,
34.46901
],
[
52.2076,
34.45348
],
[
52.17831,
34.45381
],
[
52.13737,
34.47217
],
[
52.03141,
34.47033
],
[
51.93017,
34.49023
],
[
51.91541,
34.44451
],
[
51.89897,
34.38614
],
[
51.86806,
34.30569
],
[
51.82,
34.15201
],
[
51.78168,
34.02024
],
[
51.73943,
33.92501
],
[
51.70179,
33.83608
],
[
51.65752,
33.70137
],
[
51.54035,
33.4268
],
[
51.52512,
33.38398
],
[
51.4958,
33.3356
],
[
51.44937,
33.23951
],
[
51.42716,
33.16679
],
[
51.40182,
33.06367
],
[
51.3634,
32.98993
],
[
51.34672,
32.91794
],
[
51.32141,
32.87128
],
[
51.2664,
32.6516
],
[
51.23106,
32.48914
],
[
51.20507,
32.29943
],
[
51.16934,
32.07204
],
[
51.1508,
31.97069
],
[
51.13949,
31.8706
],
[
51.13728,
31.70108
],
[
51.13263,
31.62517
],
[
51.1191,
31.52805
],
[
51.08803,
31.30808
],
[
51.06756,
31.15402
],
[
50.99689,
31.13589
],
[
50.95574,
31.12393
],
[
50.93721,
31.1177
],
[
50.92171,
31.09714
],
[
50.90721,
31.08228
],
[
50.8909,
31.07671
],
[
50.84758,
31.043
],
[
50.7346,
30.95449
],
[
50.52917,
30.79495
],
[
50.4994,
30.77167
],
[
50.48368,
30.71295
],
[
50.46354,
30.63963
],
[
50.46132,
30.6289
],
[
50.45511,
30.63293
],
[
50.43845,
30.6127
],
[
50.42376,
30.5699
],
[
50.42164,
30.55162
],
[
50.40604,
30.51815
],
[
50.39558,
30.50879
],
[
50.38195,
30.47954
],
[
50.32586,
30.39378
],
[
50.29453,
30.35951
],
[
50.26486,
30.33643
],
[
50.25778,
30.31004
],
[
50.24634,
30.28063
],
[
50.22903,
30.26774
],
[
50.18994,
30.2224
],
[
50.18091,
30.21798
],
[
50.16218,
30.2255
],
[
50.14369,
30.23776
],
[
50.13303,
30.23166
],
[
50.11478,
30.23418
],
[
50.08751,
30.23467
],
[
50.05339,
30.21647
],
[
50.03091,
30.21478
],
[
50.00816,
30.2016
],
[
49.95806,
30.17323
],
[
49.9348,
30.18623
],
[
49.92008,
30.19057
],
[
49.89046,
30.17741
],
[
49.83993,
30.15933
],
[
49.80218,
30.19935
],
[
49.75538,
30.19921
],
[
49.69172,
30.19481
],
[
49.56323,
30.17288
],
[
49.50329,
30.16781
],
[
49.459,
30.15574
],
[
49.41405,
30.12468
],
[
49.37424,
30.11152
],
[
49.33214,
30.10614
],
[
49.23068,
30.08139
],
[
49.20557,
30.07636
],
[
49.17632,
30.08126
],
[
49.14088,
30.08948
],
[
49.13227,
30.10026
],
[
49.12034,
30.14063
],
[
49.11067,
30.14782
],
[
49.05454,
30.15435
],
[
49.01042,
30.16103
],
[
48.98754,
30.16486
],
[
48.97725,
30.17264
],
[
48.92938,
30.23371
],
[
48.91232,
30.24705
],
[
48.8892,
30.25526
],
[
48.86788,
30.25988
],
[
48.8302,
30.25662
],
[
48.77143,
30.25854
],
[
48.72721,
30.25507
],
[
48.6695,
30.23987
],
[
48.56247,
30.23094
],
[
48.50009,
30.22887
],
[
48.41243,
30.24079
],
[
48.213,
30.28787
],
[
48.15789,
30.3029
],
[
48.13357,
30.30171
],
[
48.05351,
30.29445
],
[
47.96978,
30.30973
],
[
47.91599,
30.31322
],
[
47.85884,
30.30052
],
[
47.8276,
30.29059
],
[
47.79247,
30.2623
],
[
47.75315,
30.27486
],
[
47.7404,
30.27392
],
[
47.72084,
30.21455
],
[
47.70569,
30.12985
],
[
47.69383,
30.0688
],
[
47.67141,
29.99311
],
[
47.65685,
29.89882
],
[
47.63792,
29.83431
],
[
47.62534,
29.80075
],
[
47.62718,
29.74939
],
[
47.63537,
29.68184
],
[
47.58942,
29.57482
],
[
47.55006,
29.5017
],
[
47.49814,
29.45195
],
[
47.45969,
29.41467
],
[
47.4303,
29.37051
],
[
47.33885,
29.24453
],
[
47.32377,
29.22576
],
[
47.30789,
29.20682
],
[
47.27122,
29.20243
],
[
47.25495,
29.19737
],
[
47.2455,
29.18709
],
[
47.23985,
29.17093
],
[
47.22769,
29.13168
],
[
47.1724,
29.01439
],
[
47.12864,
28.91717
],
[
47.11337,
28.86019
],
[
47.10136,
28.86359
],
[
47.0479,
28.84916
],
[
47.03916,
28.85336
],
[
47.02463,
28.83238
]
],
"_debug_sub_zones_info": ,
"_debug":
"trip_distance": 1314516,
"trip_time": 56015,
"zone_distance": 10385.483746984,
"zone_time": 560,
"out_zone_distance": 1297603.4600007,
"out_zone_time": 55455,
"transmit_distance": null,
"transmit_time": null,
"tariff_price_prefix": "night_"
发现有点相同的问题,但解决方案 in this topic 仅适用于前几个坐标
【问题讨论】:
【参考方案1】:route_polyline
的值是一个嵌套数组,但是你必须将内部数组直接解码为lat/long
。
将Polyline
结构更改为
struct Polyline: Decodable
let lat: Double
let long: Double
init(from decoder: Decoder) throws
var longLat = try decoder.unkeyedContainer()
long = try longLat.decode(Double.self)
lat = try longLat.decode(Double.self)
请避免 snake_cased 变量。您可以使用 .convertFromSnakeCase
键解码策略将这些键解码为 lowerCamelCased 变量。
【讨论】:
以上是关于使用 Codable 解析嵌套 JSON 数据问题的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Codable 和 Swift 解析这个嵌套的 JSON?
iOS swift Codable 不能与 Alamofire 一起使用 JSON 嵌套数据?