JSON array of unkeyed containers (to parse in swift)

南笙酒味 提交于 2021-02-08 07:59:55

问题


How do I parse this? The array is unnamed, the objects are unnamed? I also need to sort it and find overlaps between events IF you guys have any advice there too it will be a huge help for me.

[{"title": "Evening Picnic", "start": "November 10, 2018 6:00 PM", "end": "November 10, 2018 7:00 PM"},
{"title": "Nap Break", "start": "November 8, 2018 12:56 PM", "end": "November 8, 2018 1:30 PM"}, 
{"title": "Football Game", "start": "November 3, 2018 6:14 PM", "end": "November 3, 2018 9:44 PM"}]    

I'm new to swift and I'm wondering how to deal with this


回答1:


Your JSON doesn't required you to implement an unkeyed container to parse it unkeyed container sample. What you need is a custom DateFormatter and DateDecodingStrategy. To sort your events you would need to conform it to Comparable protocol

This DateFormatter assumes your date string is a fixed date format with a local time:

extension Formatter {
    static let custom: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "MMMM d, yyyy h:mm a"
        return formatter
    }()
}

The custom DateDecodingStrategy:

extension JSONDecoder.DateDecodingStrategy {
    static let monthDayYearTime = custom {
        let container = try $0.singleValueContainer()
        let string = try container.decode(String.self)
        guard let date = Formatter.custom.date(from: string) else {
            throw DecodingError.dataCorruptedError(in: container,
                  debugDescription: "Invalid date: " + string)
        }
        return date
    }
}

Your Codable Event structure:

struct Event: Codable {
    let title: String
    let start: Date
    let end: Date
}

Conforming it to Comparable protocol

extension Event: Comparable {
    static func < (lhs: Event, rhs: Event) -> Bool { lhs.start < rhs.start }
}

A custom description:

extension Event: CustomStringConvertible {
    var description: String {
        "Title: \(title) - Start: \(Formatter.custom.string(from: start)) - End: \(Formatter.custom.string(from: end))"
    }
}

Playground testing:

Your JSON string:

let json = """
[{"title": "Evening Picnic", "start": "November 10, 2018 6:00 PM", "end": "November 10, 2018 7:00 PM"},
 {"title": "Nap Break", "start": "November 8, 2018 12:56 PM", "end": "November 8, 2018 1:30 PM"},
 {"title": "Football Game", "start": "November 3, 2018 6:14 PM", "end": "November 3, 2018 9:44 PM"}]
"""

Decoding your JSON

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .monthDayYearTime
do {
    let events = try decoder.decode([Event].self, from: Data(json.utf8))
    print(events.sorted())
} catch {
    print(error)
}

This will print

[Title: Football Game - Start: November 3, 2018 6:14 PM - End: November 3, 2018 9:44 PM, Title: Nap Break - Start: November 8, 2018 12:56 PM - End: November 8, 2018 1:30 PM, Title: Evening Picnic - Start: November 10, 2018 6:00 PM - End: November 10, 2018 7:00 PM]



来源:https://stackoverflow.com/questions/60132436/json-array-of-unkeyed-containers-to-parse-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!