NetNewsWire/Frameworks/RSParser/Feeds/FeedParser.swift

77 lines
1.6 KiB
Swift
Raw Normal View History

//
// FeedParser.swift
// RSParser
//
// Created by Brent Simmons on 6/20/17.
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
//
import Foundation
2017-06-25 19:23:30 +02:00
// FeedParser knows about the various syndication feed types.
// It might be a good idea to do a plugin-style architecture here instead
// but feed formats dont appear all that often, so its probably not necessary.
public struct FeedParser {
2017-06-25 19:23:30 +02:00
static let minNumberOfBytesRequired = 128
public static func feedType(_ parserData: ParserData) -> FeedType {
2017-06-25 19:23:30 +02:00
// Can call with partial data while still downloading, for instance.
// If theres not enough data, return .unknown. Ask again when theres more data.
// If its definitely not a feed, return .notAFeed.
2017-06-25 19:23:30 +02:00
if parserData.data.count < minNumberOfBytesRequired {
return .unknown
}
let nsdata = parserData.data as NSData
if nsdata.isProbablyJSONFeed() {
2017-06-25 19:23:30 +02:00
return .jsonFeed
}
if nsdata.isProbablyRSSInJSON() {
2017-06-25 19:23:30 +02:00
return .rssInJSON
}
if nsdata.isProbablyHTML() {
2017-06-25 19:23:30 +02:00
return .notAFeed
}
if nsdata.isProbablyRSS() {
2017-06-25 19:23:30 +02:00
return .rss
}
if nsdata.isProbablyAtom() {
2017-06-25 19:23:30 +02:00
return .atom
}
return .notAFeed
}
public static func parseFeed(_ parserData: ParserData) throws -> ParsedFeed? {
2017-06-25 19:23:30 +02:00
do {
let type = feedType(parserData)
2017-06-25 19:23:30 +02:00
switch type {
2017-06-25 19:23:30 +02:00
case .jsonFeed:
return try JSONFeedParser.parse(parserData)
2017-06-25 19:23:30 +02:00
case .rssInJSON:
return try RSSInJSONParser.parse(parserData)
2017-06-25 19:23:30 +02:00
case .rss:
return RSSParser.parse(parserData)
case .atom:
return AtomParser.parser(parserData)
case .unknown, .notAFeed:
return nil
}
2017-06-25 19:23:30 +02:00
}
catch { throw error }
}
}