{"id":15039577,"url":"https://github.com/nmdias/feedkit","last_synced_at":"2025-05-14T06:12:23.762Z","repository":{"id":38238501,"uuid":"63501164","full_name":"nmdias/FeedKit","owner":"nmdias","description":"FeedKit is a Swift library for Reading and Generating RSS, Atom, and JSON feeds.","archived":false,"fork":false,"pushed_at":"2025-03-22T21:17:21.000Z","size":2271,"stargazers_count":1242,"open_issues_count":4,"forks_count":183,"subscribers_count":19,"default_branch":"main","last_synced_at":"2025-04-03T16:04:01.114Z","etag":null,"topics":["atom","atom-feed-parser","atom-reader","feed-parser","feedkit","parsing","rss","rss-feed-parser","rss-reader","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nmdias.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-16T20:30:52.000Z","updated_at":"2025-04-03T07:49:55.000Z","dependencies_parsed_at":"2024-01-07T22:23:29.863Z","dependency_job_id":"bff69fc9-c6f5-4593-bc1c-355790eff085","html_url":"https://github.com/nmdias/FeedKit","commit_stats":{"total_commits":613,"total_committers":31,"mean_commits":"19.774193548387096","dds":0.1174551386623165,"last_synced_commit":"1f59632e76daae411bae5a4e0d10ebbea56979b7"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nmdias%2FFeedKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nmdias%2FFeedKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nmdias%2FFeedKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nmdias%2FFeedKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nmdias","download_url":"https://codeload.github.com/nmdias/FeedKit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248313560,"owners_count":21082877,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atom","atom-feed-parser","atom-reader","feed-parser","feedkit","parsing","rss","rss-feed-parser","rss-reader","swift"],"created_at":"2024-09-24T20:43:21.235Z","updated_at":"2025-04-10T23:24:45.821Z","avatar_url":"https://github.com/nmdias.png","language":"Swift","readme":"\u003cimg src=\"./FeedKit.png\" width=\"500\"\u003e\u003cbr\u003e\n\n[![CI](https://github.com/nmdias/FeedKit/actions/workflows/ci.yml/badge.svg)](https://github.com/nmdias/FeedKit/actions/workflows/ci.yml)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fnmdias%2FFeedKit%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/nmdias/FeedKit)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fnmdias%2FFeedKit%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/nmdias/FeedKit)\n\nFeedKit is a Swift library for Reading and Generating RSS, Atom, and JSON feeds.\n\n### FeedKit v10 (Release Candidate) :warning:\n\nFeedKit **[`v10`](https://github.com/nmdias/FeedKit)** is now in Release Candidate (RC) and introduces a new parsing engine, features, and improvements. While this version is feature-complete and extensively tested, it may still have some minor issues to address before the final release.\n\nIt should be stable enough :eyes:, but if stable enough is not enough, consider using **[`v9`](https://github.com/nmdias/FeedKit/releases/tag/9.1.2)**.\n\n# Features\n\n- [x] [Atom](https://tools.ietf.org/html/rfc4287)\n- [x] [RSS](http://cyber.law.harvard.edu/rss/rss.html)\n- [x] [JSON](https://jsonfeed.org)\n- [x] Namespaces\n  - [x] [Atom](http://www.w3.org/2005/Atom)\n  - [x] [Dublin Core](http://purl.org/dc/elements/1.1/)\n  - [x] [Syndication](http://purl.org/rss/1.0/modules/syndication/)\n  - [x] [Content](http://purl.org/rss/1.0/modules/content/)\n  - [x] [Media RSS](http://search.yahoo.com/mrss/)\n  - [x] [Geo RSS](http://www.georss.org/georss)\n  - [x] [GML](http://www.opengis.net/gml)\n  - [x] [iTunes](http://www.itunes.com/dtds/podcast-1.0.dtd)\n  - [x] [YouTube](http://www.youtube.com/xml/schemas/2015)\n- [x] Examples\n- [x] [Documentation](https://swiftpackageindex.com/nmdias/FeedKit/main/documentation/feedkit)\n- [x] Unit Tests\n\n## Feed Reader\n\nFeed reading can be made with a **dedicated** type, such as `RSSFeed`, `AtomFeed` and `JSONFeed`, or a **universal** type `Feed`.\n\n### Dedicated\n\nWhen you know the type of feed to be read, use a dedicated type.\n\n```swift\ntry await RSSFeed(urlString: \"https://developer.apple.com/news/rss/news.rss\")\n```\n\n### Universal\n\nWhen you don't know the type of feed, use the universal `Feed` enum type.\n\nThe `Feed` enum type handles **RSS**, **Atom** and **JSON** feeds and will determine the type of feed before reading, parsing and decoding occurs.\n\n```swift\n// Read any type of feed\nlet feed = try await Feed(urlString: \"https://surprise.me/feed\")\n\n// Use a switch to get the resulting feed model\nswitch feed {\ncase let .atom(feed): // An AtomFeed instance\ncase let .rss(feed): // An RSSFeed instance\ncase let .json(feed): // A JSONFeed instance\n}\n```\n\n#### Manual Feed Type Detection\n\nThe 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\nthe overhead of parsing and decoding**.\n\n\u003cdetails\u003e\n  \u003csummary\u003eShow\u003c/summary\u003e\n\n```swift\nlet feedType = try FeedType(data: data)\n\n// Detect feed type\nswitch feedType {\ncase .rss: // RSS feed detected\ncase .atom: // Atom feed detected\ncase .json: // JSON feed detected\n}\n\n// Or feed content type\nif feedType.isXML {\n  // XML feed detected\n} else if feedType.isJson {\n  // JSON feed detected\n}\n```\n\n\u003c/details\u003e\n\n### Initializers\n\nAll feed types conform to `FeedInitializable`, sharing multiple common initializers. They provide a flexible way to read feeds from the most common sources.\n\n\u003cdetails\u003e\n  \u003csummary\u003eShow\u003c/summary\u003e\n\nFrom a URL `String`:\n\n```swift\ninit(urlString: String) async throws\n```\n\nFrom a `URL`, handling both local file URLs and remote URLs:\n\n```swift\ninit(url: URL) async throws\n```\n\nFrom a local file `URL`:\n\n```swift\ninit(fileURL url: URL) throws\n```\n\nFrom a remote `URL`:\n\n```swift\ninit(remoteURL url: URL) async throws\n```\n\nFrom an XML or JSON `String`:\n\n```swift\ninit(string: String) throws\n```\n\nFrom raw `Data`:\n\n```swift\ninit(data: Data) throws\n```\n\n\u003c/details\u003e\n\n## Feed Generator\n\n### XML\n\nTo generate an XML string for any given XML feed, create an instance of an `RSSFeed` or `AtomFeed` and populate it with the necessary data.\n\n```swift\nlet feed = RSSFeed(\n  channel: .init(\n    title: \"Breaking News\",\n    link: \"http://www.breakingnews.com/\",\n    description: \"Get the latest updates as they happen.\",\n    // ...\n    items: [\n      .init(\n        title: \"Breaking News: All Hearts are Joyful\",\n        link: \"http://breakingnews.com/2025/01/09/joyful-hearts\",\n        description: \"A heartwarming story of unity and celebration.\"\n        // ...\n      ),\n    ]\n  )\n)\n```\n\nThen call `toXMLString(formatted:)` to generate the XML string.\n\n```swift\ntry feed.toXMLString(formatted: true)\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eOutput\u003c/summary\u003e\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003crss version=\"2.0\"\u003e\n  \u003cchannel\u003e\n    \u003ctitle\u003eBreaking News\u003c/title\u003e\n    \u003clink\u003ehttp://www.breakingnews.com/\u003c/link\u003e\n    \u003cdescription\u003eGet the latest updates as they happen.\u003c/description\u003e\n    \u003citem\u003e\n      \u003ctitle\u003eBreaking News: All Hearts are Joyful\u003c/title\u003e\n      \u003clink\u003ehttp://breakingnews.com/2025/01/09/joyful-hearts\u003c/link\u003e\n      \u003cdescription\u003eA heartwarming story of unity and celebration.\u003c/description\u003e\n    \u003c/item\u003e\n  \u003c/channel\u003e\n\u003c/rss\u003e\n```\n\n\u003c/details\u003e\n\n### JSON\n\nIn the same way, you can create an instance of a `JSONFeed`, populate it, and then call `toJSONString(formatted:)` to generate a JSON string.\n\n```swift\ntry feed.toJSONString(formatted: true)\n```\n\n## Feed Models\n\nThe **RSS**, **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.\n\n\u003cdetails\u003e\n\u003csummary\u003ePreview\u003c/summary\u003e\n\n#### RSS\n\n```swift\nchannel.title\nchannel.link\nchannel.description\nchannel.language\nchannel.copyright\nchannel.managingEditor\nchannel.webMaster\nchannel.pubDate\nchannel.lastBuildDate\nchannel.categories\nchannel.generator\nchannel.docs\nchannel.cloud\nchannel.rating\nchannel.ttl\nchannel.image\nchannel.textInput\nchannel.skipHours\nchannel.skipDays\n// ...\nchannel.dublinCore\nchannel.syndication\nchannel.iTunes\nchannel.atom\n// ...\n\nlet item = channel.items?.first\n\nitem?.title\nitem?.link\nitem?.description\nitem?.author\nitem?.categories\nitem?.comments\nitem?.enclosure\nitem?.guid\nitem?.pubDate\nitem?.source\n//...\nitem?.dublinCore\nitem?.content\nitem?.iTunes\nitem?.media\n// ...\n```\n\n#### Atom\n\n```swift\nfeed.title\nfeed.subtitle\nfeed.links\nfeed.updated\nfeed.authors\nfeed.contributors\nfeed.id\nfeed.generator\nfeed.icon\nfeed.logo\nfeed.rights\n// ...\n\nlet entry = feed.entries?.first\n\nentry?.title\nentry?.summary\nentry?.authors\nentry?.contributors\nentry?.links\nentry?.updated\nentry?.categories\nentry?.id\nentry?.content\nentry?.published\nentry?.source\nentry?.rights\n// ...\nentry?.media\nentry?.youTube\n```\n\n#### JSON\n\n```swift\nfeed.version\nfeed.title\nfeed.homePageURL\nfeed.feedUrl\nfeed.description\nfeed.userComment\nfeed.nextUrl\nfeed.icon\nfeed.favicon\nfeed.author\nfeed.expired\nfeed.hubs\n// ...\n\nlet item = feed.items?.first\n\nitem?.id\nitem?.url\nitem?.externalUrl\nitem?.title\nitem?.contentText\nitem?.contentHtml\nitem?.summary\nitem?.image\nitem?.bannerImage\nitem?.datePublished\nitem?.dateModified\nitem?.author\nitem?.url\nitem?.tags\nitem?.attachments\n// ...\n```\n\n\u003c/details\u003e\n\n## Installation\n\nTo add FeedKit to your Xcode project, follow these steps:\n\n- Open your project in Xcode and go to the \"File\" menu.\n- Select \"Add Package Dependencies…\"\n- Enter the \"Package URL\": https://github.com/nmdias/FeedKit\n- Select \"Add Package\"\n\n## License\n\nFeedKit is released under the MIT license. See [LICENSE](https://github.com/nmdias/FeedKit/blob/master/LICENSE) for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnmdias%2Ffeedkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnmdias%2Ffeedkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnmdias%2Ffeedkit/lists"}