Skip to content

Instantly share code, notes, and snippets.

@mingsai
Forked from kharrison/RSSFeed.swift
Created January 15, 2019 09:56
Show Gist options
  • Save mingsai/f5a7608fbd65e06a25648f48193dce37 to your computer and use it in GitHub Desktop.
Save mingsai/f5a7608fbd65e06a25648f48193dce37 to your computer and use it in GitHub Desktop.
Swift Decodable With Multiple Custom Dates
import Foundation
extension DateFormatter {
static let iso8601Full: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
formatter.calendar = Calendar(identifier: .iso8601)
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter
}()
static let yyyyMMdd: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.calendar = Calendar(identifier: .iso8601)
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter
}()
}
public struct RSSFeed: Codable {
public struct Feed: Codable {
public struct Podcast: Codable {
public let name: String
public let artistName: String
public let url: URL
public let releaseDate: Date
}
public let title: String
public let country: String
public let updated: Date
public let podcasts: [Podcast]
private enum CodingKeys: String, CodingKey {
case title
case country
case updated
case podcasts = "results"
}
}
public let feed: Feed
}
public typealias Feed = RSSFeed.Feed
public typealias Podcast = Feed.Podcast
extension Podcast {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
artistName = try container.decode(String.self, forKey: .artistName)
url = try container.decode(URL.self, forKey: .url)
let dateString = try container.decode(String.self, forKey: .releaseDate)
let formatter = DateFormatter.yyyyMMdd
if let date = formatter.date(from: dateString) {
releaseDate = date
} else {
throw DecodingError.dataCorruptedError(forKey: .releaseDate, in: container, debugDescription: "Date string does not match format expected by formatter.")
}
}
}
let json = """
{
"feed": {
"title":"Top Audio Podcasts",
"country":"gb",
"updated":"2017-11-16T02:02:55.000-08:00",
"results":[
{
"artistName":"BBC Radio",
"name":"Blue Planet II: The Podcast",
"releaseDate":"2017-11-12",
"url":"https://itunes.apple.com/gb/podcast/blue-planet-ii-the-podcast/id1296222557?mt=2"
},
{
"artistName":"Audible",
"name":"The Butterfly Effect with Jon Ronson",
"releaseDate":"2017-11-03",
"url":"https://itunes.apple.com/gb/podcast/the-butterfly-effect-with-jon-ronson/id1258779354?mt=2"
},
{
"artistName":"TED",
"name":"TED Talks Daily",
"releaseDate":"2017-11-16",
"url":"https://itunes.apple.com/gb/podcast/ted-talks-daily/id160904630?mt=2"
}
]
}
}
"""
let data = Data(json.utf8)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(DateFormatter.iso8601Full)
let rssFeed = try! decoder.decode(RSSFeed.self, from: data)
let feed = rssFeed.feed
print(feed.title, feed.country, feed.updated)
feed.podcasts.forEach {
print($0.name)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment