簡體   English   中英

來自嵌套 JSON 的 Swift4 中的 JSONDecoder

[英]JSONDecoder in Swift4 from nested JSON

使用 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))

Coordinates-Struct 中的 Coordinates-Initializer(見下面的代碼),我得到了以下帖子 我試圖與 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]?

廣泛的解決方案是添加一個初始化程序,以便能夠分配一個默認的非可選值。

vadian的幫助下,我終於找到了匹配的 Struct。 非常感謝瓦迪安!

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
            }
        }

        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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM