使用Swift4、iOS11.1、Xcode9.1,
尝试在 Swift4 的可解码结构中匹配 JSON 文件,最终得到以下错误消息:
"Expected to decode Array<Any> but found a dictionary instead."
--> 发现两个拼写错误后 - 仍然有问题!
错误消息现在显示:The Error-Messages now says: intValue: Optional(5))], debugDescription: "No value associated with key photos (\"photos\").", underlyingError: nil))
坐标结构内部的坐标初始化器(参见下面的代码),我得到了以下post 。我尝试与 JSON 文件完全匹配的其他所有内容(参见最底部)...
目前,我没有看到任何拼写错误 - 难道我还遗漏了其他内容吗?
JSON 文件的获取方式如下。这里可能有什么问题吗?
let myTask = session.dataTask(with: myRequest) { (data, response, error) in
if (error != nil) {
print("Error1 fetching JSON data")
}
else {
do {
//Decode retrived data with JSONDecoder and assing type of Station object
let stationData = try JSONDecoder().decode(Station.self, from: data!)
//Get back to the main queue
DispatchQueue.main.async {
print(stationData)
}
}
catch let error {
print(error)
}
}
}
myTask.resume()
该结构如下所示(请参阅下面的 JSON):
struct Station: Codable {
let htmlAttributions: [String]
let nextPageToken: String
let results: [Result]
let status: String
struct Result: Codable {
let formattedAddress: String
let geometry: Geometry
let icon: String
let id: String
let name: String
let photos: [Photo]
let placeID: String
let rating: Double
let reference: String
let types: [String]
struct Geometry: Codable {
let location: Coordinates
let viewport: Viewport
struct Coordinates: Codable {
let lat: Double
let lng: Double
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
lat = try values.decode(Double.self, forKey: .lat)
lng = try values.decode(Double.self, forKey: .lng)
}
enum CodingKeys : String, CodingKey {
case lat
case lng
}
}
struct Viewport: Codable {
let northeast: Coordinates
let southwest: Coordinates
enum CodingKeys : String, CodingKey {
case northeast
case southwest
}
}
enum CodingKeys : String, CodingKey {
case location
case viewport
}
}
// !!!!!!!!!!!! something wrong here ???? !!!!!!!!!!!
struct Photo: Codable {
let height: Int
let htmlAttributions: [String]
let photoReference: String
let width: Int
enum CodingKeys : String, CodingKey {
case height
case htmlAttributions = "html_attributions"
case photoReference = "photo_reference"
case width
}
}
enum CodingKeys : String, CodingKey {
case formattedAddress = "formatted_address"
case geometry
case icon
case id
case name
case photos
case placeID = "place_id"
case rating
case reference
case types
}
}
enum CodingKeys : String, CodingKey {
case htmlAttributions = "html_attributions"
case nextPageToken = "next_page_token"
case results
case status
}
}
这是 JSON 文件:
{
"html_attributions" : [],
"next_page_token" : "F3ddaOzOcyo94AA2skDm",
"results" : [
{
"formatted_address" : "Strasse 1, 6003 Luzern, Switzerland",
"geometry" : {
"location" : {
"lat" : 47.04951260000001,
"lng" : 8.310404999999999
},
"viewport" : {
"northeast" : {
"lat" : 47.0508615802915,
"lng" : 8.311753980291503
},
"southwest" : {
"lat" : 47.0481636197085,
"lng" : 8.309056019708498
}
}
},
"icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
"id" : "a3d600a6e78105b6ce2b5f5a3fac98ca1910a09b",
"name" : "Luzern",
"photos" : [
{
"height" : 4000,
"html_attributions" : [
"\u003ca href=\"https://maps.google.com/maps/contrib/113951418385089253589/photos\"\u003eAlex Marcu\u003c/a\u003e"
],
"photo_reference" : "CmRaAAAAYHK1VHDFlkbzXuMnF2MLEdew-36lgHC2lS1Cxg_DELgP-ckZH7G6aa-81LGDpR5rPZY1XMw64mytsjXIrdB5n3QQmXjGgelwZEbHaetT2jpy9SeaHDH3qUGGAUW-7BtZEhCxXy2dxGSv6A_g7fipsCr5GhRZlPuliykokXIkqfqIN_vMWzmYyA",
"width" : 3000
}
],
"place_id" : "ChIJqQIbhpj7j0cRjUguIM__gZw",
"rating" : 4.4,
"reference" : "CmRSAAAAzBZCshpypXcbMhrBQIdK2zISd3Q40QRSFO0KKhIrTejnGiZIoASuVqCVtmNBnFsodLWrYtOP-RmwCqDBDVbMheeCbFk7f0L8gwixLx_SGhYTDqPd6B2IwPWWXH5Pb6lxEhBoQtWj-kB-g1ZiOZ74hswNGhSd9Kf9Qj1P2_fdQCTO_VCoTU09JA",
"types" : [
"transit_station",
"bus_station",
"train_station",
"point_of_interest",
"establishment"
]
},
{ ...more results... },
{ ...more results... }
],
"status" : "OK"
}
最佳答案
错误消息表明 results
数组的第 6 个元素(索引 5)没有键 photos
。
简单的解决方案是将数组声明为可选
let photos: [Photo]?
广泛的解决方案是添加一个初始值设定项以便能够分配默认的非可选值。
关于Swift4 中的 JSONDecoder 来自嵌套 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47536013/