92 lines
1.9 KiB
Swift
Raw Normal View History

2024-11-09 09:37:57 -08:00
//
// FeedParser.swift
// RSParser
//
// Created by Brent Simmons on 6/20/17.
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
//
import Foundation
import RSParserObjC
// FeedParser handles RSS, Atom, JSON Feed, and RSS-in-JSON.
// You dont need to know the type of feed.
public typealias FeedParserCallback = (_ parsedFeed: ParsedFeed?, _ error: Error?) -> Void
public struct FeedParser {
private static let parseQueue = DispatchQueue(label: "FeedParser parse queue")
public static func canParse(_ parserData: ParserData) -> Bool {
let type = feedType(parserData)
switch type {
case .jsonFeed, .rssInJSON, .rss, .atom:
return true
default:
return false
}
}
public static func mightBeAbleToParseBasedOnPartialData(_ parserData: ParserData) -> Bool {
let type = feedType(parserData, isPartialData: true)
switch type {
case .jsonFeed, .rssInJSON, .rss, .atom, .unknown:
return true
default:
return false
}
}
public static func parse(_ parserData: ParserData) throws -> ParsedFeed? {
// This is generally fast enough to call on the main thread 
// but its probably a good idea to use a background queue if
// you might be doing a lot of parsing. (Such as in a feed reader.)
do {
let type = feedType(parserData)
switch type {
case .jsonFeed:
return try JSONFeedParser.parse(parserData)
case .rssInJSON:
return try RSSInJSONParser.parse(parserData)
case .rss:
return RSSParser.parse(parserData)
case .atom:
return AtomParser.parse(parserData)
case .unknown, .notAFeed:
return nil
}
}
catch { throw error }
}
public static func parse(_ parserData: ParserData, _ completion: @escaping FeedParserCallback) {
parseQueue.async {
do {
let parsedFeed = try parse(parserData)
DispatchQueue.main.async {
completion(parsedFeed, nil)
}
}
catch {
DispatchQueue.main.async {
completion(nil, error)
}
}
}
}
}