Skip to content

Instantly share code, notes, and snippets.

@romanroibu
Forked from kharrison/RSSFeed.swift
Last active April 9, 2021 15:28
Show Gist options
  • Select an option

  • Save romanroibu/089ec641757604bf78a390654c437cb0 to your computer and use it in GitHub Desktop.

Select an option

Save romanroibu/089ec641757604bf78a390654c437cb0 to your computer and use it in GitHub Desktop.
Swift Decodable With Multiple Custom Dates (https://useyourloaf.com/blog/swift-codable-with-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
}
typealias Feed = RSSFeed.Feed
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)
}
@ekilah
Copy link
Copy Markdown

ekilah commented Feb 21, 2019

nice, i like the changes from the blog post's version

@felipebweber
Copy link
Copy Markdown

felipebweber commented Mar 2, 2021

thanks, this code is awesome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment