Module Index

Jump to a section:

class

RSSParser

Parses RSS XML feeds into RSSStory objects. Supports loading multiple feeds concurrently with O(1) deduplication by link URL. Thread-safe โ€” all shared state mutations are serialized on an internal serial queue.

Properties

PropertyTypeDescription
delegateRSSParserDelegate?Delegate notified when feed loading completes or fails
stories[RSSStory]Read-only. Accumulated stories from all parsed feeds

Methods

MethodDescription
loadFeeds(_ urls: [String]) Parse stories from multiple feed URLs concurrently. Calls delegate on the main thread when all feeds complete. Cancels any in-flight load from a previous call. Stories are deduplicated by link URL.
parseData(_ data: Data) โ†’ [RSSStory] Parse stories from in-memory XML data synchronously. Useful for testing and offline scenarios. Returns an array of parsed stories directly.

Usage

import FeedReaderCore class MyFeedController: RSSParserDelegate { let parser = RSSParser() func fetchFeeds() { parser.delegate = self parser.loadFeeds([ "https://feeds.bbci.co.uk/news/world/rss.xml", "https://techcrunch.com/feed/" ]) } func parserDidFinishLoading(stories: [RSSStory]) { // Stories from all feeds, deduplicated print("Loaded \(stories.count) stories") } func parserDidFailWithError(_ error: Error?) { print("Feed load failed: \(error?.localizedDescription ?? "unknown")") } }
protocol

RSSParserDelegate

Delegate protocol for receiving RSS parsing results. Callbacks are always delivered on the main thread.

Required Methods

MethodDescription
parserDidFinishLoading(stories: [RSSStory]) Called when all requested feeds have finished loading. The stories array contains deduplicated results from all feeds.
parserDidFailWithError(_ error: Error?) Called when a feed fails to load. The error may be nil for non-HTTP errors.
class

RSSStory

Represents a single parsed RSS story with title, body, link, and optional image URL. Provides URL validation and HTML sanitization. Conforms to NSObject and Sendable.

Properties

PropertyTypeDescription
titleStringThe story headline
bodyStringThe story description with HTML tags stripped and entities decoded
linkStringThe story's unique URL (used for equality and deduplication)
imagePathString?Optional thumbnail image URL (only set if URL passes safety validation)

Initializer

public init?( title: String, body: String, link: String, imagePath: String? = nil )

Returns nil if:

  • title is empty
  • body is empty after HTML stripping
  • link is not a valid HTTP/HTTPS URL

Static Methods

MethodDescription
isSafeURL(_ urlString: String?) โ†’ Bool Validates that a URL uses only allowed schemes (http, https). Rejects javascript:, file:, data:, and other unsafe schemes.
stripHTML(_ html: String) โ†’ String Strips HTML tags via regex and decodes common HTML entities (&, <, >, ", ',  ).

Equality

Two RSSStory instances are equal if their link properties match. This is how deduplication works across multiple feeds.

class

FeedItem

Represents an RSS feed source with a name, URL, and enabled state. Conforms to NSSecureCoding for persistent storage and Sendable for thread safety.

Properties

PropertyTypeDescription
nameStringDisplay name for the feed
urlStringRSS feed URL string
isEnabledBoolWhether the feed is currently enabled for fetching
identifierStringComputed. Lowercased URL used for deduplication

Initializer

public init( name: String, url: String, isEnabled: Bool = false )

Static Properties

PropertyDescription
presets: [FeedItem] 10 built-in feed sources: BBC World News, BBC Technology, BBC Science, BBC Business, NPR News, Reuters World, TechCrunch, Ars Technica, Hacker News, The Verge

Usage

// Use built-in presets let feeds = FeedItem.presets let enabledUrls = feeds .filter { $0.isEnabled } .map { $0.url } // Create custom feed let custom = FeedItem( name: "My Blog", url: "https://myblog.com/rss.xml", isEnabled: true )
enum

NetworkReachability

Provides a simple check for network connectivity using SystemConfiguration. Uses SCNetworkReachability to check for a default network route.

Static Methods

MethodDescription
isConnected() โ†’ Bool Returns true if the device currently has a network route available. Does not guarantee that a specific host is reachable โ€” only that the system believes a route exists.

Usage

import FeedReaderCore if NetworkReachability.isConnected() { parser.loadFeeds(feedUrls) } else { // Load from cache or show offline UI showCachedStories() }

ArticleArchiveExporter

Exports RSSStory objects as self-contained HTML archive files for offline reading, sharing, or long-term preservation. Supports single and batch export with 4 visual themes (light, dark, sepia, newspaper).

Initialization

let exporter = ArticleArchiveExporter(options: .default) // Or with custom options: var opts = ArticleArchiveExporter.ExportOptions( theme: .sepia, includeMetadata: true, includeTableOfContents: true, includeWordCount: true, includeEstimatedReadTime: true ) let exporter = ArticleArchiveExporter(options: opts)

Types

TypeDescription
ThemeVisual theme enum: .light, .dark, .sepia, .newspaper. Each provides backgroundColor, textColor, accentColor, and fontFamily.
ExportOptionsConfigures theme, metadata inclusion, table of contents, word count, read time, and optional custom CSS.
ExportResultContains the exported filename, htmlContent, articleCount, totalWordCount, and exportDate.

Methods

MethodDescription
exportArticle(_ story: RSSStory) โ†’ ExportResultExport a single article as a standalone HTML file.
exportArticles(_ stories: [RSSStory]) โ†’ ExportResult?Batch export multiple articles into a single HTML file with table of contents. Returns nil if the array is empty.
save(_ result: ExportResult, to directory: URL) โ†’ URL?Write the export result to disk. Returns the file URL on success.
listArchives(in directory: URL) โ†’ [(filename, date, size)]List all .html archive files in a directory.
deleteArchive(named:in:) โ†’ BoolDelete an archive file by name.
countWords(_ text: String) โ†’ IntCount words in a text string.
estimateReadTime(wordCount: Int) โ†’ IntEstimate reading time in minutes (assumes 200 wpm).

Usage

let exporter = ArticleArchiveExporter(options: .init(theme: .dark)) let result = exporter.exportArticle(story) if let url = exporter.save(result, to: archiveDir) { print("Saved to \(url)") }

FeedHealthMonitor

Monitors feed health by analyzing article publication dates. Classifies feeds as healthy, warning, stale, or dead and generates actionable reports with scores and recommendations.

Types

TypeDescription
FeedHealthStatusEnum: .healthy, .warning, .stale, .dead. Comparable by severity.
FeedHealthResultPer-feed result with status, score (0โ€“100), daysSinceLastArticle, averageUpdateInterval, issues, and recommendations.
FeedHealthReportAggregate report with results, overallScore, overallStatus, statusCounts, and JSON export via jsonDict.
FeedHealthConfigConfigures thresholds: warningDays, staleDays, deadDays, minimumArticleCount, maxUpdateIntervalDays.

Methods

MethodDescription
checkFeed(feedName:feedURL:articleDates:) โ†’ FeedHealthResultAnalyze a single feed's health based on its article publication dates.
generateReport(feeds:) โ†’ FeedHealthReportGenerate a comprehensive health report for multiple feeds at once.
detectTrend(articleDates:) โ†’ Double?Detect publishing frequency trend. Returns a multiplier (>1 = accelerating, <1 = decelerating).

Usage

let monitor = FeedHealthMonitor() let result = monitor.checkFeed( feedName: "Swift Blog", feedURL: "https://swift.org/blog/feed.xml", articleDates: dates ) print(result.summary) // "Swift Blog: healthy (92/100)"

KeywordExtractor

Extracts keywords and themes from article text using TF-based frequency analysis with stop-word filtering. Works on individual stories or across collections for theme detection.

Properties

PropertyDescription
minimumWordLength: IntMinimum character length for a word to be considered (default: 3).
defaultCount: IntDefault number of keywords to return (default: 5).

Methods

MethodDescription
extractKeywords(from text: String, count: Int?) โ†’ [String]Extract top keywords from raw text.
extractTags(from story: RSSStory, count: Int?) โ†’ [String]Extract keyword tags from a story's title and body.
extractThemes(from stories: [RSSStory], count: Int?) โ†’ [String]Extract common themes across a collection of stories.

Usage

let extractor = KeywordExtractor() let tags = extractor.extractTags(from: story, count: 8) // ["swift", "concurrency", "async", "await", ...] let themes = extractor.extractThemes(from: allStories) // ["programming", "apple", "ios", "development", "swift"]

TextUtilities

Shared text processing utilities. Centralises stop words, HTML entity escaping, and word counting to eliminate duplication across modules.

Key Members

MemberDescription
stopWords: Set<String>~100 common English stop words used by KeywordExtractor and ArticleQuizGenerator.
wordCount(_ text: String) โ†’ IntUnicode-aware word count using enumerateSubstrings.
decodeHTMLEntities(_ html: String) โ†’ StringDecodes named and numeric HTML entities.

OPMLManager

Import and export feed subscriptions in OPML 2.0 format โ€” the industry-standard interchange format for RSS readers. Includes XXE attack prevention and payload size limiting.

Methods

MethodDescription
importFeeds(from data: Data) โ†’ [FeedItem]Parse an OPML document and return feed items. Throws OPMLError on invalid input.
exportFeeds(_ feeds: [FeedItem]) โ†’ DataGenerate a well-formed OPML 2.0 XML document from feed items.

Error Handling

OPMLError cases: invalidData, parsingFailed, noFeedsFound, encodingFailed, payloadTooLarge (DoS defense), and externalEntityDetected (XXE prevention).

FeedCacheManager

HTTP conditional GET caching for RSS feeds using ETag and Last-Modified headers. Avoids re-downloading unchanged content, reducing bandwidth significantly for feeds that update infrequently.

Methods

MethodDescription
applyCacheHeaders(to request: inout URLRequest, for url: URL)Attaches stored ETag / If-Modified-Since headers to the request.
isNotModified(_ response: HTTPURLResponse) โ†’ BoolReturns true if the server responded with 304 Not Modified.
storeCacheMetadata(from response: HTTPURLResponse, for url: URL)Persist caching headers after a successful 200 response.

ArticleDigestComposer

Newsletter-style digest composer. Generates formatted digests from articles on daily, weekly, or monthly cadence. Produces both plain-text and HTML output.

Key Types

TypeDescription
DigestPeriodCoreCadence enum: .daily (1 day), .weekly (7 days), .monthly (30 days). Each has a days lookback property.
DigestResultContains title, htmlContent, plainTextContent, articleCount, and period.

ArticleQuizGenerator

Generates comprehension quiz questions from article content using extractive NLP โ€” entirely offline, no API needed. Supports factual, vocabulary, and inference question categories.

Key Types

TypeDescription
QuizQuestionA multiple-choice question with question, choices, correctIndex, sourceExcerpt, and category.
QuizCategoryEnum: .factual, .vocabulary, .inference.

Methods

MethodDescription
generateQuiz(from text: String, count: Int) โ†’ [QuizQuestion]Generate quiz questions from article text. Returns up to count questions.

FeedContentCalendar

Publication pattern detection and schedule forecasting. Analyses when feeds publish, detects regular schedules, predicts upcoming publications, and alerts when expected content is late.

Key Types

TypeDescription
DayProfilePer-weekday stats: weekday, totalArticles, averageArticles, peakHour, isRegularDay.
PublicationScheduleDetected schedule pattern with predicted next publication dates.

FeedTopicRadar

Emerging topic detection via z-score burst analysis. Tracks topic frequency across time windows, classifies lifecycle phases (Emerging โ†’ Trending โ†’ Saturated โ†’ Declining โ†’ Dormant), and generates early-warning alerts.

Methods

MethodDescription
recordObservation(topic:feedURL:feedName:articleId:timestamp:confidence:)Record a topic mention from an article.
scan() โ†’ TopicRadarReportProduce a full scan: bursts, phase classifications, cross-feed correlations, and portfolio health score (0โ€“100).

FeedTrendForecaster

Predicts which topics are about to peak by analysing keyword momentum. Computes breakout probabilities and classifies trends into phases: emerging, accelerating, peaking, declining.

Key Types

TypeDescription
TrendPhaseEnum with emoji: .emerging ๐ŸŒฑ, .accelerating ๐Ÿš€, .peaking โšก, .declining ๐Ÿ“‰.
TrendForecastPer-topic forecast with phase, momentum, breakoutProbability, and predictedPeakDate.

FeedSentimentRadar

Lexicon-based sentiment tracking across feeds. Scores article tone on a 5-point scale, detects mood shifts over time, and generates proactive alerts on significant sentiment changes.

Key Types

TypeDescription
SentimentPolarity5-level enum from .veryNegative (โˆ’1.0) to .veryPositive (+1.0).
SentimentReportAggregate sentiment analysis with per-feed breakdown, trending direction, and shift alerts.

FeedIntelligenceBrief

Autonomous daily intelligence briefing generator. Correlates articles across feeds to produce structured, prioritised briefs with narrative threads, emerging signals, cross-feed correlations, and actionable insights.

Methods

MethodDescription
generateBrief(articles:feedMap:previousKeywords:) โ†’ IntelligenceBrief?Produce a brief with executiveSummary, narrativeThreads, emergingSignals, blindSpots, and actionableInsights.

FeedEditorialDriftCompass

Monitors feed sources for silent editorial drift โ€” when a feed's content diverges from its established identity (e.g., a tech blog starts covering politics). Classifies drift types and predicts future identity state.

Methods

MethodDescription
ingestArticle(feedURL:title:topics:)Record an article's topics for a feed.
analyzeDrift(feedURL:) โ†’ DriftReportReturns driftScore (0โ€“100), driftType (topicInvasion / identityErosion / pivot / dilution), velocity, and prediction.

FeedNarrativeArcTracker

Tracks developing storylines across articles over time. Detects narrative phases (Emerging โ†’ Rising โ†’ Climax โ†’ Falling โ†’ Resolution โ†’ Dormant), alerts on turning points, and forecasts story resolution timelines.

Notifications

NotificationDescription
.narrativeTurningPointDetectedA followed story hit an inflection point.
.narrativePhaseChangedA story moved to a new narrative phase.

FeedSourceCredibility

Builds trust profiles for RSS sources based on observable content signals: claim consistency, correction/retraction patterns, citation density, hedging language, and temporal reliability. Assigns 5-tier credibility ratings (Platinum โ†’ Untrusted).

Notifications

NotificationDescription
.credibilityAlertGeneratedA source's credibility changed significantly.
.credibilityTierChangedA source moved up or down a reliability tier.

FeedCrossReferenceEngine

Cross-article fact corroboration and contradiction detection. Extracts factual claims (numbers, dates, statistics), cross-references across sources, and scores reliability with full provenance audit trails.

Capabilities

FeedDebateArena

Argument extraction engine that identifies opposing viewpoints on the same topic across feeds. Classifies stances (for/against/mixed/neutral), calculates balance scores, and detects echo chambers.

Notifications

NotificationDescription
.debateTopicCreatedA new debate topic was identified.
.debateEchoChamberDetectedOne-sided coverage detected across sources.
.debateConsensusFormingMultiple sources converging on a shared position.

FeedAttentionAllocator

Autonomous attention budget manager. Tracks how reading attention is distributed across topics, detects 5 types of attention sinks (rabbit holes, doom scrolling, echo chambers, novelty traps, obligation reads), and suggests reallocation.

Key Output

FieldDescription
diversityScoreShannon entropy-based diversity score 0โ€“100.
attentionEfficiencyHow well attention aligns with stated priorities (0โ€“100).
sinksDetected attention traps with type classification.
reallocationsSuggested attention shifts with rationale.

FeedBlindSpotDetector

Identifies systematic gaps in reading habits โ€” topics adjacent to interests but consistently missing from feeds. Uses keyword co-occurrence, Shannon entropy, and temporal analysis to score blind spots 0โ€“100 with portfolio health grades.

Methods

MethodDescription
ingest(_ article: BlindSpotArticle)Add an article to the analysis corpus.
detect() โ†’ BlindSpotReportReturns blind spots with severity scores, coverage map, and portfolio health grade (Aโ€“F).

FeedContextualPrimer

Reading preparation engine that primes the reader before an article. Analyses target content against reading history to produce background refreshers, concept familiarity maps, knowledge readiness scores, and optimal reading order suggestions.

Methods

MethodDescription
recordReading(story:)Register a story as read to build the reader's concept history.
preparePrimer(for story:) โ†’ ContextualPrimerReturns readinessScore (0โ€“100), backgroundRefreshers, conceptFamiliarity, and blindSpots.
suggestReadingOrder(_ stories:) โ†’ [RSSStory]Orders articles for progressive concept scaffolding.

FeedInterestEvolver

Tracks how reading interests change over time. Creates periodic snapshots and analyses them to detect emerging interests, fading topics, cyclical patterns, stable passions, and predicted future interests.

Methods

MethodDescription
recordSnapshot(articles:)Record a reading snapshot from recent articles.
analyzeEvolution() โ†’ EvolutionReportReturns biography (narrative timeline), emergingTopics, fadingTopics, predictions, and diversityMetrics.

FeedPredictiveInterestEngine

Forecasts future reading interests before the user searches for them. Analyses interest trajectory vectors, curiosity signals, and co-occurrence patterns. Self-tracks prediction accuracy and adapts.

Methods

MethodDescription
recordInteraction(topic:feedURL:articleId:interactionType:dwellSeconds:timestamp:)Record a reading interaction with dwell time and type.
predict() โ†’ [InterestPrediction]Returns predicted interests ranked by confidence with momentum vectors.
surfaceArticles(from candidates:) โ†’ [RankedArticle]Proactively rank articles by predicted relevance.

FeedKnowledgeGraph

Personal knowledge graph builder. Extracts concepts from reading history, maps relationships, detects knowledge gaps, suggests learning paths, tracks concept decay, and scores expertise depth across topics.

Methods

MethodDescription
ingest(_ article: KGArticle)Add article concepts to the knowledge graph.
analyze() โ†’ KnowledgeReportReturns clusters (topic groups), gaps, learningPaths, decayingConcepts, and expertiseProfile.

FeedReadingAutopilot

Autonomous session planner that curates optimal article sequences for a given time budget. Considers priority scoring, reading time estimates, topic diversity, cognitive load balancing, and reading momentum curves.

Methods

MethodDescription
planSession(articles:timeBudgetMinutes:preferences:) โ†’ ReadingSessionReturns an ordered playlist, totalMinutes, diversityScore (0โ€“100), cognitiveProfile, and a human-readable sessionBrief.

FeedReadingFatigueAdvisor

Watches cognitive load across reading sessions. Analyses 10 weighted fatigue signals (volume, depth, diversity, sentiment, timing, continuity) to produce a 0โ€“100 fatigue score with Aโ€“F grade and 5-tier verdict (fresh โ†’ burnout).

Methods

MethodDescription
analyze(sessions:) โ†’ FatigueReportReturns fatigueScore (0โ€“100), grade (Aโ€“F), verdict (fresh/engaged/mildFatigue/heavyFatigue/burnout), and a prioritised playbook of recommendations.

FeedReadingGoalTracker

Tracks daily/weekly reading goals (article count, topic diversity, minutes read). Manages streaks, progress reporting, and adaptive goal suggestions based on reading patterns.

Key Types

TypeDescription
ReadingGoalGoal config with type (.articleCount/.topicDiversity/.minutesRead), period (.daily/.weekly), and target value.
GoalProgressCurrent progress with current, target, percentage, and streak count.

FeedSubscriptionROI

Measures per-feed return on investment based on engagement vs. volume. Classifies feeds into 5 ROI tiers (Platinum/Gold/Silver/Bronze/Deficit), detects 6 subscription anti-patterns, and generates prune/promote recommendations.

Methods

MethodDescription
recordArticle(feedURL:feedName:wasRead:dwellSeconds:wasSaved:wasShared:)Record engagement for an article.
analyzePortfolio() โ†’ ROIReportReturns portfolioHealth (0โ€“100), per-feed reports with tier classification, detected anti-patterns, and recommendations.

FeedSourceDiversityGuardian

Echo-chamber detection and diversity advisor. Monitors reading across 5 axes: topic concentration, source concentration, geographic diversity, publication type balance, and recency bias. Flags drops below healthy thresholds with corrective recommendations.

Methods

MethodDescription
analyze(readingHistory:subscriptions:config:) โ†’ DiversityReportReturns overallScore (0โ€“100), grade (Aโ€“F), per-axis breakdown, and actionable recommendations.

FeedSerendipityEngine

Discovers unexpected connections between articles from different feeds using keyword co-occurrence and topic bridging. Surfaces surprising cross-topic reads the user wouldn't normally find.

Key Types

TypeDescription
SerendipityConnectionA discovered link between two articles with bridgeKeywords, serendipityScore (0โ€“1), explanation, and connectionType.