nmdias/FeedKit
66.5
Adequate · 1 October 2026
14k
lines of production code
Swift
primary language
2
measurements over time
What this system is
FeedKit is a Swift library that parses and serializes RSS, Atom, RDF, and JSON feeds, supporting a wide range of standard and custom namespaces like iTunes, Media RSS, and GeoRSS. It provides a unified API for handling feed data, including robust date parsing and geographic metadata extraction. The system also includes a modular XML parsing engine (XMLKit) and example applications to demonstrate usage on iOS and macOS.
Features
Add Atom feed parsing and serialization support
Introduces the data models and serialization logic for the Atom feed specification (RFC 4287) within the \Sources/FeedKit/Feeds/Atom\ directory. This change adds the \AtomFeed\ and \AtomFeedEntry\ structures along with their associated components (such as authors, links, categories, and content), enabling the library to parse and generate Atom XML documents.
Sources/FeedKit/Feeds/Atom · high confidence
Add FeedKit parse benchmark and performance tracker
Developers can now measure and track FeedKit parsing performance using a new benchmark suite in the Benchmarks directory. The suite includes a frozen corpus of six real-world feeds (Atom, RSS, and JSON) and a Swift measurement tool that reports median parse times. A shell script automates the build and run process, appending results to a central PERFORMANCE.md tracker to facilitate regression detection and version comparisons.
Benchmarks · high confidence
Add dark mode logo asset
The Assets directory now includes a new FeedKit-dark.svg file, providing a specific logo variant for dark mode interfaces.
Assets · high confidence
Add example views for fetching and displaying RSS feeds
The Example project now includes SwiftUI views that demonstrate fetching and displaying RSS feeds. AppleNewsView fetches the Apple Developer News feed, while ConcurrencyView loads multiple technology news feeds concurrently using Swift concurrency. Supporting views (FeedView and FeedItemView) display feed metadata and individual item details.
Example/Example/Views · high confidence
Add support for Simple GeoRSS in feed items
FeedKit now parses and encodes Simple GeoRSS geographic data within feed items. This change introduces new model structs—GeoRSS, GeoRSSSimple, and GeoRSSSimplePoint—located in the Namespaces/Geo folder, enabling the library to handle \<georss:point\> and \<georss:elev\> elements for location and elevation information.
Sources/FeedKit/Namespaces/Geo · high confidence
Added Example project for FeedKit
An example iOS application project has been added to demonstrate the FeedKit library. This new project configures the build environment to include FeedKit and its dependency XMLKit as framework references, allowing users to build and run the example app directly from the workspace.
Example/Example.xcodeproj · high confidence
Expanded Media RSS namespace support with new model types
The Media RSS namespace models have been expanded to include several new elements, allowing the library to parse additional metadata from feeds. Specifically, \media:group\ now supports \media:thumbnail\, \media:description\, and \media:community\ child elements, aligning with patterns observed in YouTube feeds. New top-level and nested model types have been added for \media:community\ (star ratings, statistics, tags), \media:backLinks\, \media:comments\, \media:embed\, \media:location\, \media:peerLink\, \media:prices\, \media:scenes\, \media:status\, \media:responses\, and \media:rights\. This enables richer parsing of media-specific metadata such as community engagement stats, geographic location data, and player embed parameters.
Sources/FeedKit/Namespaces/Media · high confidence
New FeedKit example app for macOS
An example application has been added to demonstrate FeedKit usage on macOS. The app is built with SwiftUI and features a tabbed interface with views for Apple News parsing and concurrency examples. It includes an entitlements file that configures the app sandbox with read-only file access and network client permissions, allowing the example to function correctly within macOS security constraints.
Example/Example · high confidence
New String extension for XML character escaping
A new \escapeCharacters()\ method has been added to the \String\ type within the XMLKit library. This extension allows users to safely prepare text for inclusion in XML documents by automatically replacing special characters (\&\, \\<\, \\>\, \'\, and \"\) with their corresponding XML entities (\&\, \<\, \>\, \'\, and \"\).
Sources/XMLKit/Extensions · high confidence
New String parsing extensions for feed data
Added new String extension methods to simplify parsing common feed data formats: \toBool()\ converts strings like "true" or "1" to booleans, \toDuration()\ parses time strings (e.g., "HH:MM:SS") into TimeInterval values, \toGMLPosition()\ extracts latitude and longitude from space-separated coordinate strings, \toKeywords()\ splits comma-separated keyword lists, and \toMediaTags()\ parses comma-separated media tags with optional weights into MediaTag objects.
Sources/FeedKit/Extensions · high confidence
New namespace models for Atom, Content, GML, and YouTube feeds
FeedKit now includes dedicated model structs for several RSS/Atom namespaces, allowing users to parse and access additional metadata. The new Atom namespace provides \Atom\ and \AtomLink\ (with attributes like \href\, \rel\, \type\, \hreflang\, \title\, and \length\) to support WebSub discovery and link relations. The Content namespace adds a \Content\ struct to handle entity-encoded or CDATA-escaped body content. Geographic data is supported via the GML namespace's \GMLPoint\ struct, which parses latitude and longitude from \\<gml:pos\>\ elements. Finally, the YouTube namespace introduces a \YouTube\ struct to extract \channelID\ and \videoID\ metadata from feed entries.
(repo-wide) · high confidence
Support for the Podcastindex namespace
FeedKit now parses the Podcastindex namespace, adding support for podcast-specific metadata tags such as \\<podcast:guid\>\, \\<podcast:liveItem\>\, \\<podcast:transcript\>\, \\<podcast:alternateEnclosure\>\, and \\<podcast:value\>\. This allows users to access structured data for features like live streaming status, episode transcripts, alternative media enclosures, and payment recipients directly from parsed feeds.
Sources/FeedKit/Namespaces/Podcast · high confidence
Architecture
Reorganized namespace models into dedicated folder structure
The Dublin Core and Syndication namespace model files have been moved into their respective \Sources/FeedKit/Namespaces/DublinCore\ and \Sources/FeedKit/Namespaces/Syndication\ directories. This change restructures the project's source layout to better separate namespace-specific logic, improving code organization without altering the public API or parsing behavior.
Sources/FeedKit/Namespaces/DublinCore, Sources/FeedKit/Namespaces/Syndication · high confidence
Behavioural changes
JSON Feed 1.1 support and encoding improvements
The JSON Feed parser now supports the JSON Feed 1.1 specification, adding \authors\ (array) and \language\ fields to both the feed and individual items, while deprecating the singular \author\ field. The \version\ property is now implicitly derived from the presence of these 1.1-specific fields rather than being explicitly supplied. Additionally, the encoder no longer includes nil values in the output JSON, and date parsing performance has been optimized by reusing static \RFC3339DateFormatter\ instances.
Sources/FeedKit/Feeds/JSON · high confidence
RSS feed model files reorganized into Feeds/RSS directory
The RSS 2.0 data model files (such as RSSFeed, RSSFeedChannel, RSSFeedItem, and related types) have been moved into the Sources/FeedKit/Feeds/RSS directory. This change restructures the project layout to group RSS-specific models together, but does not alter the public API or parsing behavior for users.
Sources/FeedKit/Feeds/RSS · high confidence
Refactor feed models into separate files
The feed-related data structures in the Example app have been split into distinct files: FeedItemModel.swift and FeedModel.swift. This change organizes the model layer by separating individual feed items from the overall feed container, improving code maintainability without altering the underlying data representation or user-facing behavior.
Example/Example/Models · high confidence
Simplified feed parsing API with unified Feed enum and improved date performance
The library now uses a unified \Feed\ enum (supporting Atom, RSS, RDF, and JSON) instead of the previous \FeedParser\ class, providing a simpler initialization path from URLs, strings, or data. This change also introduces native support for RDF (RSS 1.0) feeds and several new namespaces including Comment API, Feed Paging (RFC 5005), and Podlove Simple Chapters. Additionally, date parsing has been refactored to use static, immutable strategies, significantly improving performance by avoiding the overhead of repeated \DateFormatter\ configuration.
Sources/FeedKit · high confidence
XMLDecoder now uses a two-pass approach to correctly handle namespace prefixes
The XMLDecoder implementation has been refactored to use a two-pass decoding strategy to fix issues where namespace prefixes (such as \dc\ in RSS feeds) were incorrectly matched to element names. The first pass identifies keys that act as namespace containers, and the second pass uses this information to ensure that elements sharing a prefix with a namespace container are not mistakenly decoded as that namespace's content. This change improves the accuracy of decoding XML documents that use namespaces, particularly for formats like RSS where prefix collisions are common.
Sources/XMLKit/XMLDecoder · high confidence
XMLKit module refactored with Codable support and namespace handling
The XMLKit module has been restructured to improve modularity and separation of concerns. \XMLDocument\ now conforms to \Codable\, allowing it to be encoded and decoded directly. The internal parsing logic has been refactored from \XMLParser\ to \XMLReader\, and the \XMLStack\ implementation has been changed from a class to a struct. New types \XMLElement\ and \XMLAttributesElement\ have been introduced to support generic, type-safe decoding of XML elements with attributes. Additionally, the \XMLEncoder\ now supports \XMLNamespaceCodable\, enabling proper handling of namespaced XML elements, and the \XMLHeader\ structure provides explicit control over XML document headers.
Sources/XMLKit · high confidence
iTunes namespace models moved and episode type changed to String
The iTunes podcasting namespace models have been reorganized into the \Sources/FeedKit/Namespaces/iTunes\ directory, with new files for categories, images, owners, and subcategories. Additionally, the \episode\ property in the \ITunes\ struct is now typed as \String\ instead of an integer, aligning with the iTunes Podcasting Tags specification where episode numbers can be non-numeric (e.g., "bonus").
Sources/FeedKit/Namespaces/iTunes · high confidence
Test coverage
Added XMLKitTestable protocol for test resource loading and debugging; Added comprehensive test coverage for XMLKit; Added test infrastructure for debugging feed parsing failures; Expanded test coverage for feed parsing and serialization.
Dependencies
Swift Package Manager manifest updated to Swift 6.0 with expanded platform support and modularized XMLKit
The project's Package.swift has been updated to require Swift 6.0 and now explicitly supports macOS 12+, iOS 15+, watchOS 8+, tvOS 15+, and visionOS 1. The package structure has been refactored to include a separate XMLKit library target, which is a dependency for the main FeedKit library. Additionally, a new Benchmarks sub-package was added to allow performance testing against specific FeedKit checkouts, and test resources for various feed formats (RSS, Atom, JSON, etc.) are now explicitly registered in the manifest.
(dependencies) · high confidence
Housekeeping
Repository maintenance and documentation updates
This change introduces several repository-level improvements: a new \.spi.yml\ configuration to enable Swift Package Index documentation generation for the FeedKit target, a \.swiftformat\ configuration file to enforce consistent code style (Swift 6.0, 2-space indentation, explicit property types, etc.), and a \format.sh\ script to automate running SwiftFormat. The \.gitignore\ file is updated to exclude additional build artifacts and Xcode user data. Documentation is refreshed with an architectural review, performance benchmarking results, and updated README content including dark mode logo support and installation instructions. The LICENSE file copyright year is updated to 2025.
(repo-wide) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 66 → 67 (+1.0)
- Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.
Lenses
- Code Health 99 → 99 (-0.4)
- Architecture 90 → 86 (-4.0)
- Maturity 55 → 80 (+25.6)
- Readiness 55 → 48 (-6.9)
- Security 92 → 82 (-10.0)
Resolved (5)
- Documentation: no installation or build instructions (README.md)
- Documentation: no licence statement (README.md)
- Documentation: no usage examples (README.md)
- Members sharing a duplicated core (11 members, 50+ identical tokens) (Sources/FeedKit/Feeds/Atom/AtomFeed.swift)
- Orphaned files with no living knowledge
New (37)
- Duplicated block (11 lines × 2) (Sources/FeedKit/Namespaces/DublinCore/DublinCore.swift)
- Duplicated block (13 lines × 2) (Sources/FeedKit/Namespaces/Media/MediaContent.swift)
- Duplicated block (14 lines × 2) (Sources/FeedKit/Feeds/Atom/AtomFeedEntry.swift)
- Duplicated block (22 lines × 2) (Sources/FeedKit/FeedError.swift)
- Duplicated block (32 lines × 2) (Sources/FeedKit/FeedNamespace.swift)
- Duplicated block (5 lines × 2) (Sources/FeedKit/Feeds/Atom/AtomFeedSource.swift)
- Duplicated block (7 lines × 2) (Sources/FeedKit/FeedError.swift)
- Duplicated block (9–10 lines × 2) (Sources/FeedKit/Namespaces/Podcast/PodcastAlternateEnclosure.swift)
- Hotspot: Sources/FeedKit/FeedNamespace.swift (Sources/FeedKit/FeedNamespace.swift)
- Inconsistent method naming for XML serialization. 'toXmlDocument' uses camelCase 'Xml', while 'toXMLString' uses uppercase 'XML'. This is a minor casing inconsistency.
- Inconsistent parameter naming for URL sources. 'url' and 'fileURL' are distinct, but 'remoteURL' is redundant with 'url' (as URLs are generally remote) and inconsistent with the naming convention of 'fileURL'. It creates ambiguity: when should a user pass 'url' vs 'remoteURL'?
- Leaked secret: jwt (Benchmarks/corpus/json-daringfireball.json)
- Low coverage: Sources/FeedKit/FeedError.swift (Sources/FeedKit/FeedError.swift)
- Low coverage: Sources/FeedKit/FeedInitializable.swift (Sources/FeedKit/FeedInitializable.swift)
- Low coverage: Sources/FeedKit/Feeds/Atom/AtomFeedSource.swift (Sources/FeedKit/Feeds/Atom/AtomFeedSource.swift)
- Low coverage: Sources/FeedKit/Namespaces/Media/MediaCopyright.swift (Sources/FeedKit/Namespaces/Media/MediaCopyright.swift)
- Low coverage: Sources/FeedKit/Namespaces/Media/MediaRights.swift (Sources/FeedKit/Namespaces/Media/MediaRights.swift)
- Low coverage: Sources/FeedKit/Namespaces/Media/MediaTag.swift (Sources/FeedKit/Namespaces/Media/MediaTag.swift)
- Low coverage: Sources/FeedKit/Namespaces/Podcast/PodcastAlternateEnclosure.swift (Sources/FeedKit/Namespaces/Podcast/PodcastAlternateEnclosure.swift)
- Low coverage: Sources/FeedKit/Namespaces/Podcast/PodcastImage.swift (Sources/FeedKit/Namespaces/Podcast/PodcastImage.swift)
- …and 17 more
Changes since last survey
- 24 commits — 20 feature/other, 4 fixes
By area
- (root) — 8 commits
- Sources/FeedKit — 7 commits
- Sources/XMLKit — 4 commits
- Tests/FeedKitTests — 4 commits
- Benchmarks/corpus — 1 commit
Notable commits
- fix: Fix JSON accessor names in README (#237)
- fix: Fix RSS parsing when a namespace prefix matches an element name (#215)
- fix: Fix XMLError.cdataDecoding error code (#244)
- fix: Fix crash when serializing a permissive date (#245)
- change: Add Atom XML serialization (#236)
- change: Add a parse benchmark and a performance tracker (#243)
- change: Add architectural review of the FeedKit and XMLKit codebase
- change: Add support for Feed Paging and Archiving (RFC 5005) (#229)
- change: Add support for RDF (RSS 1.0) (#175) (#232)
- change: Add support for the Comment API namespace (#216) (#230)
- change: Add support for the Podcast namespace (#198) (#231)
- change: Add support for the Podlove Simple Chapters (psc) namespace (#201) (#233)
- change: Escape XML text and attribute values when serializing (#234)
- change: Expose JSONFeed.version as public private(set) (#240)
- change: Inspect a longer prefix when detecting the feed type (#226)
- change: Parse feed dates with static ParseStrategy caches (#251 #239)
- change: Prefer text-bearing elements when decoding repeated children (#190) (#227)
- change: Record the 10.9.4 parse benchmark (#252)
- change: Rename FeedType.isJson to isJSON (#238)
- change: Replace placeholder example domains with reserved domains (#210) (#228)
- …and 4 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
nmdias/FeedKit was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 1 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 545aba8b9357fb00ffe51483b659519d96a9d635 — the exact code this score is about.
- Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-e569280dd5e2.