【问题标题】:Nested JSON parsing in swift, problems with structs快速嵌套JSON解析,结构问题
【发布时间】:2020-02-22 11:40:58
【问题描述】:

我想解析一个带有嵌套结构的 JSON。

我创建了几个带有必填字段的结构,现在尝试使用它们。

这就是 JSON 的样子(Eventful API):

{
  "last_item": null,
   "total_items": "1194",
   "first_item": null,
   "page_number": "1",
   "page_size": "10",
   "page_items": null,
   "search_time": "0.143",
   "page_count": "120",
   "events": {
     "event": [
       {
         "watching_count": null,
         "olson_path": "Europe/London",
         "calendar_count": null,
         "comment_count": null,
         "region_abbr": "London",
         "postal_code": null,
         "going_count": null,
         "all_day": "0",
         "latitude": "51.5009088",
         "groups": null,
         "url": "http://london.eventful.com/events/zucchero-/E0-001-120935308-6?utm_source=apis&utm_medium=apim&utm_campaign=apic",
         "id": "E0-001-120935308-6",
         "privacy": "1",
         "city_name": "London",
         "link_count": null,
         ...

这就是我想要做的:

struct Event: Codable {

    var id: String
    var title: String
    var latitude: Double
    var longitude: Double
    var url: URL
    var venueAddress: String
    var regionName: String
    var image: [Image]

    enum CodingKeys: String, CodingKey {
        case id
        case title
        case latitude
        case longitude
        case url
        case venueAddress = "venue_address"
        case regionName = "region_name"
        case image

}

struct Events: Codable {
    var events: [Event]
}


let apiUrlString = "http://api.eventful.com/json/events/......."
var event = [Event]()   


func parse(json: Data) {
    DispatchQueue.global().async { [weak self] in
        let decoder = JSONDecoder()
        if let jsonEvents = try? decoder.decode(Events.self, from: json) {
            self?.event = jsonEvents.events
        }
    }
}

@IBAction func searchButtonTapped(_ sender: UIButton) {

    if let url = URL(string: apiUrlString) {
        if let data = try? Data(contentsOf: url) {
            parse(json: data)
            print(event)
        } else {
            showError()
        }
    } else {
        showError()
    }
} 

Parse func 工作正常,但我的数组总是空的。我想我可以对我的 Event 和 Events 结构进行一些更改。如果您有任何建议,请提供帮助。

【问题讨论】:

  • JSONs 事件属性不包含数组 ([Event]) 而是一个字典 ([String: [Event]])。除了latitude 和longitude 是Strings,而不是Doubles。而且由于解析是异步发生的,所以您打印event 太早了。
  • 主要问题在这里,try? decoder...。当您使用 try? 而不是捕获和打印错误时,您会错过解决问题的重要信息,因为 json 解码错误通常对诊断问题非常有帮助。
  • 是的,纬度和经度你说得对,谢谢!我尝试使用字典来存储属性,但是在点击按钮后它仍然是空的 =(

标签: ios json swift api parsing


【解决方案1】:

这是您的 json 响应的模型,试试这个。

// MARK: - Event
struct Event: Codable {
    let lastItem: JSONNull?
    let totalItems: String
    let firstItem: JSONNull?
    let pageNumber, pageSize: String
    let pageItems: JSONNull?
    let searchTime, pageCount: String
    let events: Events

    enum CodingKeys: String, CodingKey {
        case lastItem = "last_item"
        case totalItems = "total_items"
        case firstItem = "first_item"
        case pageNumber = "page_number"
        case pageSize = "page_size"
        case pageItems = "page_items"
        case searchTime = "search_time"
        case pageCount = "page_count"
        case events
    }
}

// MARK: - Events
struct Events: Codable {
    let event: [EventElement]
}

// MARK: - EventElement
struct EventElement: Codable {
    let watchingCount: JSONNull?
    let olsonPath: String
    let calendarCount, commentCount: JSONNull?
    let regionAbbr: String
    let postalCode, goingCount: JSONNull?
    let allDay, latitude: String
    let groups: JSONNull?
    let url: String
    let id, privacy, cityName: String
    let linkCount: JSONNull?

    enum CodingKeys: String, CodingKey {
        case watchingCount = "watching_count"
        case olsonPath = "olson_path"
        case calendarCount = "calendar_count"
        case commentCount = "comment_count"
        case regionAbbr = "region_abbr"
        case postalCode = "postal_code"
        case goingCount = "going_count"
        case allDay = "all_day"
        case latitude, groups, url, id, privacy
        case cityName = "city_name"
        case linkCount = "link_count"
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 2019-06-28
    相关资源
    最近更新 更多