[](https://github.com/nmdias/FeedKit/actions/workflows/ci.yml)
[](https://swiftpackageindex.com/nmdias/FeedKit)
[](https://swiftpackageindex.com/nmdias/FeedKit)
FeedKit is a Swift library for Reading and Generating RSS, RDF, Atom, and JSON feeds.
# Features
- [x] [Atom](https://tools.ietf.org/html/rfc4287)
- [x] [RSS](http://cyber.law.harvard.edu/rss/rss.html)
- [x] [RDF](https://www.rssboard.org/rss-1-0) (RSS 1.0 and 0.90)
- [x] [JSON](https://jsonfeed.org)
- [x] Namespaces
- [x] [Atom](http://www.w3.org/2005/Atom)
- [x] [Dublin Core](http://purl.org/dc/elements/1.1/)
- [x] [Syndication](http://purl.org/rss/1.0/modules/syndication/)
- [x] [Content](http://purl.org/rss/1.0/modules/content/)
- [x] [Media RSS](http://search.yahoo.com/mrss/)
- [x] [Geo RSS](http://www.georss.org/georss)
- [x] [GML](http://www.opengis.net/gml)
- [x] [iTunes](http://www.itunes.com/dtds/podcast-1.0.dtd)
- [x] [YouTube](http://www.youtube.com/xml/schemas/2015)
- [x] [Podcast](https://podcastindex.org/namespace/1.0)
- [x] [Feed Paging and Archiving](https://datatracker.ietf.org/doc/html/rfc5005)
- [x] [Comment API](https://www.rssboard.org/comment-api)
- [x] [Podlove Simple Chapters](https://podlove.org/simple-chapters)
- [x] Examples
- [x] [Documentation](https://swiftpackageindex.com/nmdias/FeedKit/main/documentation/feedkit)
- [x] Unit Tests
## Feed Reader
Feed reading can be made with a **dedicated** type, such as `RSSFeed`, `RDFFeed`, `AtomFeed` and `JSONFeed`, or a **universal** type `Feed`.
### Dedicated
When you know the type of feed to be read, use a dedicated type.
```swift
try await RSSFeed(urlString: "https://developer.apple.com/news/rss/news.rss")
```
### Universal
When you don't know the type of feed, use the universal `Feed` enum type.
The `Feed` enum type handles **RSS**, **RDF**, **Atom** and **JSON** feeds and will determine the type of feed before reading, parsing and decoding occurs.
```swift
// Read any type of feed
let feed = try await Feed(urlString: "https://surprise.example/feed")
// Use a switch to get the resulting feed model
switch feed {
case let .atom(feed): // An AtomFeed instance
case let .rss(feed): // An RSSFeed instance
case let .rdf(feed): // An RDFFeed instance
case let .json(feed): // A JSONFeed instance
}
```
#### Manual Feed Type Detection
The universal `Feed` enum above automatically determines the feed type, so you generally don't need to do it manually. However, using a `FeedType` enum can be helpful when you want to **identify the type of feed without
the overhead of parsing and decoding**.
Show
```swift
let feedType = try FeedType(data: data)
// Detect feed type
switch feedType {
case .rss: // RSS feed detected
case .rdf: // RDF feed detected
case .atom: // Atom feed detected
case .json: // JSON feed detected
}
// Or feed content type
if feedType.isXML {
// XML feed detected
} else if feedType.isJSON {
// JSON feed detected
}
```
### Initializers
All feed types conform to `FeedInitializable`, sharing multiple common initializers. They provide a flexible way to read feeds from the most common sources.
> **Note:** The URL-fetching initializers require `URLSession`, which Foundation does not provide on WASI. On WASI, use the local `fileURL:`, `string:`, and `data:` initializers.
Show
From a URL `String`:
```swift
init(urlString: String) async throws
```
From a `URL`, handling both local file URLs and remote URLs:
```swift
init(url: URL) async throws
```
From a local file `URL`:
```swift
init(fileURL url: URL) throws
```
From a remote `URL`:
```swift
init(remoteURL url: URL) async throws
```
From an XML or JSON `String`:
```swift
init(string: String) throws
```
From raw `Data`:
```swift
init(data: Data) throws
```
## Feed Generator
### XML
To generate an XML string for any given XML feed, create an instance of an `RSSFeed` or `AtomFeed` and populate it with the necessary data.
```swift
let feed = RSSFeed(
channel: .init(
title: "Breaking News",
link: "http://www.breakingnews.example/",
description: "Get the latest updates as they happen.",
// ...
items: [
.init(
title: "Breaking News: All Hearts are Joyful",
link: "http://breakingnews.example/2025/01/09/joyful-hearts",
description: "A heartwarming story of unity and celebration."
// ...
),
]
)
)
```
Then call `toXMLString(formatted:)` to generate the XML string.
```swift
try feed.toXMLString(formatted: true)
```
Output
```xml
Breaking News
http://www.breakingnews.example/
Get the latest updates as they happen.Breaking News: All Hearts are Joyful
http://breakingnews.example/2025/01/09/joyful-hearts
A heartwarming story of unity and celebration.
```
### JSON
In the same way, you can create an instance of a `JSONFeed`, populate it, and then call `toJSONString(formatted:)` to generate a JSON string.
```swift
try feed.toJSONString(formatted: true)
```
## Feed Models
The **RSS**, **RDF**, **Atom**, and **JSON** feed models are highly comprehensive, especially when combined with all the supported namespaces. Below is a small preview of what’s available.
Preview
#### RSS
```swift
channel.title
channel.link
channel.description
channel.language
channel.copyright
channel.managingEditor
channel.webMaster
channel.pubDate
channel.lastBuildDate
channel.categories
channel.generator
channel.docs
channel.cloud
channel.rating
channel.ttl
channel.image
channel.textInput
channel.skipHours
channel.skipDays
// ...
channel.dublinCore
channel.syndication
channel.iTunes
channel.atom
// ...
let item = channel.items?.first
item?.title
item?.link
item?.description
item?.author
item?.categories
item?.comments
item?.enclosure
item?.guid
item?.pubDate
item?.source
//...
item?.dublinCore
item?.content
item?.iTunes
item?.media
// ...
```
#### RDF
```swift
feed.channel?.title
feed.channel?.link
feed.channel?.description
// ...
feed.channel?.dublinCore
feed.channel?.syndication
// In RSS 1.0 the items are siblings of the channel
let item = feed.items?.first
item?.title
item?.link
item?.description
// ...
item?.dublinCore
item?.content
```
#### Atom
```swift
feed.title
feed.subtitle
feed.links
feed.updated
feed.authors
feed.contributors
feed.id
feed.generator
feed.icon
feed.logo
feed.rights
// ...
let entry = feed.entries?.first
entry?.title
entry?.summary
entry?.authors
entry?.contributors
entry?.links
entry?.updated
entry?.categories
entry?.id
entry?.content
entry?.published
entry?.source
entry?.rights
// ...
entry?.media
entry?.youTube
```
#### JSON
```swift
feed.version
feed.title
feed.homePageURL
feed.feedURL
feed.description
feed.userComment
feed.nextURL
feed.icon
feed.favicon
feed.author
feed.expired
feed.hubs
// ...
let item = feed.items?.first
item?.id
item?.url
item?.externalURL
item?.title
item?.contentText
item?.contentHtml
item?.summary
item?.image
item?.bannerImage
item?.datePublished
item?.dateModified
item?.author
item?.url
item?.tags
item?.attachments
// ...
```
## Installation
To add FeedKit to your Xcode project, follow these steps:
- Open your project in Xcode and go to the "File" menu.
- Select "Add Package Dependencies…"
- Enter the "Package URL": https://github.com/nmdias/FeedKit
- Select "Add Package"
## Performance
Parsing speed across versions is tracked in [PERFORMANCE.md](PERFORMANCE.md). To
measure and add a row:
```sh
cd Benchmarks
./bench.sh
```
## License
FeedKit is released under the MIT license. See [LICENSE](https://github.com/nmdias/FeedKit/blob/master/LICENSE) for details.