Make progress on getting RSParser.framework to build.
This commit is contained in:
parent
6f0e4a9da6
commit
1ad4474b29
|
@ -16,7 +16,7 @@ public struct FeedParser {
|
||||||
|
|
||||||
static let minNumberOfBytesRequired = 128
|
static let minNumberOfBytesRequired = 128
|
||||||
|
|
||||||
public static func feedType(parserData: ParserData) -> FeedType {
|
public static func feedType(_ parserData: ParserData) -> FeedType {
|
||||||
|
|
||||||
// Can call with partial data — while still downloading, for instance.
|
// Can call with partial data — while still downloading, for instance.
|
||||||
// If there’s not enough data, return .unknown. Ask again when there’s more data.
|
// If there’s not enough data, return .unknown. Ask again when there’s more data.
|
||||||
|
@ -26,38 +26,40 @@ public struct FeedParser {
|
||||||
return .unknown
|
return .unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
if parserData.data.isProbablyJSONFeed() {
|
let nsdata = parserData.data as NSData
|
||||||
|
if nsdata.isProbablyJSONFeed() {
|
||||||
return .jsonFeed
|
return .jsonFeed
|
||||||
}
|
}
|
||||||
if parserData.data.isProbablyRSSInJSON() {
|
if nsdata.isProbablyRSSInJSON() {
|
||||||
return .rssInJSON
|
return .rssInJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
if parserData.data.isProbablyHTML() {
|
if nsdata.isProbablyHTML() {
|
||||||
return .notAFeed
|
return .notAFeed
|
||||||
}
|
}
|
||||||
|
|
||||||
if parserData.data.isProbablyRSS() {
|
if nsdata.isProbablyRSS() {
|
||||||
return .rss
|
return .rss
|
||||||
}
|
}
|
||||||
if parserData.data.isProbablyAtom() {
|
if nsdata.isProbablyAtom() {
|
||||||
return .atom
|
return .atom
|
||||||
}
|
}
|
||||||
|
|
||||||
return .notAFeed
|
return .notAFeed
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func parseFeed(parserData: ParserData) -> ParsedFeed? {
|
public static func parseFeed(_ parserData: ParserData) throws -> ParsedFeed? {
|
||||||
|
|
||||||
|
do {
|
||||||
let type = feedType(parserData)
|
let type = feedType(parserData)
|
||||||
|
|
||||||
switch type {
|
switch type {
|
||||||
|
|
||||||
case .jsonFeed:
|
case .jsonFeed:
|
||||||
return JSONFeedParser.parse(parserData)
|
return try JSONFeedParser.parse(parserData)
|
||||||
|
|
||||||
case .rssInJSON:
|
case .rssInJSON:
|
||||||
return RSSInJSONFeedParser.parse(parserData)
|
return try RSSInJSONParser.parse(parserData)
|
||||||
|
|
||||||
case .rss:
|
case .rss:
|
||||||
return RSSParser.parse(parserData)
|
return RSSParser.parse(parserData)
|
||||||
|
@ -69,4 +71,6 @@ public struct FeedParser {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch { throw error }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ public struct FeedParserError: Error {
|
||||||
case jsonFeedVersionNotFound
|
case jsonFeedVersionNotFound
|
||||||
case jsonFeedItemsNotFound
|
case jsonFeedItemsNotFound
|
||||||
case jsonFeedTitleNotFound
|
case jsonFeedTitleNotFound
|
||||||
|
case invalidJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
public let errorType: FeedParserErrorType
|
public let errorType: FeedParserErrorType
|
||||||
|
|
|
@ -12,10 +12,12 @@ import Foundation
|
||||||
|
|
||||||
public struct JSONFeedParser {
|
public struct JSONFeedParser {
|
||||||
|
|
||||||
public static func parse(parserData: ParserData) throws -> ParsedFeed? {
|
public static func parse(_ parserData: ParserData) throws -> ParsedFeed? {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let parsedObject = try JSONSerialization.jsonObject(with: parserData.data)
|
guard let parsedObject = try JSONSerialization.jsonObject(with: parserData.data) as? JSONDictionary else {
|
||||||
|
throw FeedParserError(.invalidJSON)
|
||||||
|
}
|
||||||
|
|
||||||
guard let version = parsedObject["version"] as? String, version.hasPrefix("https://jsonfeed.org/version/") else {
|
guard let version = parsedObject["version"] as? String, version.hasPrefix("https://jsonfeed.org/version/") else {
|
||||||
throw FeedParserError(.jsonFeedVersionNotFound)
|
throw FeedParserError(.jsonFeedVersionNotFound)
|
||||||
|
@ -27,13 +29,13 @@ public struct JSONFeedParser {
|
||||||
throw FeedParserError(.jsonFeedTitleNotFound)
|
throw FeedParserError(.jsonFeedTitleNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let authors = parseAuthors(parsedObject)
|
||||||
let homePageURL = parsedObject["home_page_url"] as? String
|
let homePageURL = parsedObject["home_page_url"] as? String
|
||||||
let feedURL = parsedObject["feed_url"] ?? parserData.url
|
let feedURL = parsedObject["feed_url"] as? String ?? parserData.url
|
||||||
let feedDescription = parsedObject["description"] as? String
|
let feedDescription = parsedObject["description"] as? String
|
||||||
let nextURL = parsedObject["next_url"] as? String
|
let nextURL = parsedObject["next_url"] as? String
|
||||||
let iconURL = parsedObject["icon_url"] as? String
|
let iconURL = parsedObject["icon_url"] as? String
|
||||||
let faviconURL = parsedObject["favicon_url"] as? String
|
let faviconURL = parsedObject["favicon_url"] as? String
|
||||||
let authors = parseAuthors(parsedObject)
|
|
||||||
let expired = parsedObject["expired"] as? Bool ?? false
|
let expired = parsedObject["expired"] as? Bool ?? false
|
||||||
let hubs = parseHubs(parsedObject)
|
let hubs = parseHubs(parsedObject)
|
||||||
|
|
||||||
|
@ -48,15 +50,15 @@ public struct JSONFeedParser {
|
||||||
|
|
||||||
private extension JSONFeedParser {
|
private extension JSONFeedParser {
|
||||||
|
|
||||||
func parseAuthors(_ dictionary: JSONDictionary) -> [ParsedAuthor]? {
|
static func parseAuthors(_ dictionary: JSONDictionary) -> [ParsedAuthor]? {
|
||||||
|
|
||||||
guard let authorDictionary = dictionary["author"] as? JSONDictionary else {
|
guard let authorDictionary = dictionary["author"] as? JSONDictionary else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = authorDictionary["name"]
|
let name = authorDictionary["name"] as? String
|
||||||
let url = authorDictionary["url"]
|
let url = authorDictionary["url"] as? String
|
||||||
let avatar = authorDictionary["avatar"]
|
let avatar = authorDictionary["avatar"] as? String
|
||||||
if name == nil && url == nil && avatar == nil {
|
if name == nil && url == nil && avatar == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -64,14 +66,14 @@ private extension JSONFeedParser {
|
||||||
return [parsedAuthor]
|
return [parsedAuthor]
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseHubs(_ dictionary: JSONDictionary) -> [ParsedHub]? {
|
static func parseHubs(_ dictionary: JSONDictionary) -> [ParsedHub]? {
|
||||||
|
|
||||||
guard let hubsArray = dictionary["hubs"] as? JSONArray else {
|
guard let hubsArray = dictionary["hubs"] as? JSONArray else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
let hubs = hubsArray.flatMap { (oneHubDictionary) -> ParsedHub? in
|
let hubs = hubsArray.flatMap { (oneHubDictionary) -> ParsedHub? in
|
||||||
guard let oneHubURL = oneHubDictionary["url"], let oneHubType = oneHubDictionary["type"] else {
|
guard let oneHubURL = oneHubDictionary["url"] as? String, let oneHubType = oneHubDictionary["type"] as? String else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return ParsedHub(type: oneHubType, url: oneHubURL)
|
return ParsedHub(type: oneHubType, url: oneHubURL)
|
||||||
|
@ -79,14 +81,14 @@ private extension JSONFeedParser {
|
||||||
return hubs.isEmpty ? nil : hubs
|
return hubs.isEmpty ? nil : hubs
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseItems(_ itemsArray: JSONArray) -> [ParsedItem] {
|
static func parseItems(_ itemsArray: JSONArray) -> [ParsedItem] {
|
||||||
|
|
||||||
return itemsArray.flatMap { (oneItemDictionary) -> ParsedItem? in
|
return itemsArray.flatMap { (oneItemDictionary) -> ParsedItem? in
|
||||||
return parseItem(oneItemDictionary)
|
return parseItem(oneItemDictionary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseItem(_ itemDictionary: JSONDictionary) -> ParsedItem? {
|
static func parseItem(_ itemDictionary: JSONDictionary) -> ParsedItem? {
|
||||||
|
|
||||||
guard let uniqueID = parseUniqueID(itemDictionary) else {
|
guard let uniqueID = parseUniqueID(itemDictionary) else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -105,8 +107,8 @@ private extension JSONFeedParser {
|
||||||
let imageURL = itemDictionary["image"] as? String
|
let imageURL = itemDictionary["image"] as? String
|
||||||
let bannerImageURL = itemDictionary["banner_image"] as? String
|
let bannerImageURL = itemDictionary["banner_image"] as? String
|
||||||
|
|
||||||
let datePublished = parseDate(itemDictionary["date_published"])
|
let datePublished = parseDate(itemDictionary["date_published"] as? String)
|
||||||
let dateModified = parseDate(itemDictionary["date_modified"])
|
let dateModified = parseDate(itemDictionary["date_modified"] as? String)
|
||||||
|
|
||||||
let authors = parseAuthors(itemDictionary)
|
let authors = parseAuthors(itemDictionary)
|
||||||
let tags = itemDictionary["tags"] as? [String]
|
let tags = itemDictionary["tags"] as? [String]
|
||||||
|
@ -115,7 +117,7 @@ private extension JSONFeedParser {
|
||||||
return ParsedItem(uniqueID: uniqueID, url: url, externalURL: externalURL, title: title, contentHTML: contentHTML, contentText: contentText, summary: summary, imageURL: imageURL, bannerImageURL: bannerImageURL, datePublished: datePublished, dateModified: dateModified, authors: authors, tags: tags, attachments: attachments)
|
return ParsedItem(uniqueID: uniqueID, url: url, externalURL: externalURL, title: title, contentHTML: contentHTML, contentText: contentText, summary: summary, imageURL: imageURL, bannerImageURL: bannerImageURL, datePublished: datePublished, dateModified: dateModified, authors: authors, tags: tags, attachments: attachments)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseUniqueID(_ itemDictionary: JSONDictionary) -> String? {
|
static func parseUniqueID(_ itemDictionary: JSONDictionary) -> String? {
|
||||||
|
|
||||||
if let uniqueID = itemDictionary["id"] as? String {
|
if let uniqueID = itemDictionary["id"] as? String {
|
||||||
return uniqueID // Spec says it must be a string
|
return uniqueID // Spec says it must be a string
|
||||||
|
@ -130,7 +132,7 @@ private extension JSONFeedParser {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDate(_ dateString: String?) -> Date? {
|
static func parseDate(_ dateString: String?) -> Date? {
|
||||||
|
|
||||||
guard let dateString = dateString, !dateString.isEmpty else {
|
guard let dateString = dateString, !dateString.isEmpty else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -138,7 +140,7 @@ private extension JSONFeedParser {
|
||||||
return RSDateWithString(dateString)
|
return RSDateWithString(dateString)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAttachments(_ itemDictionary: JSONDictionary) -> [ParsedAttachment]? {
|
static func parseAttachments(_ itemDictionary: JSONDictionary) -> [ParsedAttachment]? {
|
||||||
|
|
||||||
guard let attachmentsArray = itemDictionary["attachments"] as? JSONArray else {
|
guard let attachmentsArray = itemDictionary["attachments"] as? JSONArray else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -148,7 +150,7 @@ private extension JSONFeedParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAttachment(_ attachmentObject: JSONDictionary) -> ParsedAttachment? {
|
static func parseAttachment(_ attachmentObject: JSONDictionary) -> ParsedAttachment? {
|
||||||
|
|
||||||
guard let url = attachmentObject["url"] as? String else {
|
guard let url = attachmentObject["url"] as? String else {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -13,10 +13,12 @@ import Foundation
|
||||||
|
|
||||||
public struct RSSInJSONParser {
|
public struct RSSInJSONParser {
|
||||||
|
|
||||||
public static func parse(parserData: ParserData) throws -> ParsedFeed? {
|
public static func parse(_ parserData: ParserData) throws -> ParsedFeed? {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let parsedObject = try JSONSerialization.jsonObject(with: parserData.data)
|
guard let parsedObject = try JSONSerialization.jsonObject(with: parserData.data) as? JSONDictionary else {
|
||||||
|
throw FeedParserError(.invalidJSON)
|
||||||
|
}
|
||||||
|
|
||||||
guard let channelObject = parsedObject["channel"] as? JSONDictionary else {
|
guard let channelObject = parsedObject["channel"] as? JSONDictionary else {
|
||||||
throw FeedParserError(.rssChannelNotFound)
|
throw FeedParserError(.rssChannelNotFound)
|
||||||
|
@ -32,7 +34,7 @@ public struct RSSInJSONParser {
|
||||||
itemsObject = channelObject["items"] as? JSONArray
|
itemsObject = channelObject["items"] as? JSONArray
|
||||||
}
|
}
|
||||||
if itemsObject == nil {
|
if itemsObject == nil {
|
||||||
itemsObject == parsedObject["items"] as? JSONArray
|
itemsObject = parsedObject["items"] as? JSONArray
|
||||||
}
|
}
|
||||||
if itemsObject == nil {
|
if itemsObject == nil {
|
||||||
throw FeedParserError(.rssItemsNotFound)
|
throw FeedParserError(.rssItemsNotFound)
|
||||||
|
@ -43,7 +45,7 @@ public struct RSSInJSONParser {
|
||||||
let feedURL = parserData.url
|
let feedURL = parserData.url
|
||||||
let feedDescription = channelObject["description"] as? String
|
let feedDescription = channelObject["description"] as? String
|
||||||
|
|
||||||
let items = parseItems(itemsObject)
|
let items = parseItems(itemsObject!)
|
||||||
|
|
||||||
return ParsedFeed(type: .rssInJSON, title: title, homePageURL: homePageURL, feedURL: feedURL, feedDescription: feedDescription, nextURL: nil, iconURL: nil, faviconURL: nil, authors: nil, expired: false, hubs: nil, items: items)
|
return ParsedFeed(type: .rssInJSON, title: title, homePageURL: homePageURL, feedURL: feedURL, feedDescription: feedDescription, nextURL: nil, iconURL: nil, faviconURL: nil, authors: nil, expired: false, hubs: nil, items: items)
|
||||||
|
|
||||||
|
@ -56,19 +58,19 @@ private extension RSSInJSONParser {
|
||||||
|
|
||||||
static func parseItems(_ itemsObject: JSONArray) -> [ParsedItem] {
|
static func parseItems(_ itemsObject: JSONArray) -> [ParsedItem] {
|
||||||
|
|
||||||
return itemsObject.flatMap{ (oneItemDictionary) -> ParsedItem in
|
return itemsObject.flatMap{ (oneItemDictionary) -> ParsedItem? in
|
||||||
|
|
||||||
return parsedItemWithDictionary(oneItemDictionary)
|
return parsedItemWithDictionary(oneItemDictionary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func parsedItemWithDictionary(_ JSONDictionary: itemDictionary) -> ParsedItem? {
|
static func parsedItemWithDictionary(_ itemDictionary: JSONDictionary) -> ParsedItem? {
|
||||||
|
|
||||||
let externalURL = itemDictionary["link"] as? String
|
let externalURL = itemDictionary["link"] as? String
|
||||||
let title = itemDictionary["title"] as? String
|
let title = itemDictionary["title"] as? String
|
||||||
|
|
||||||
var contentHTML = itemDictionary["description"] as? String
|
var contentHTML = itemDictionary["description"] as? String
|
||||||
var contentText = nil
|
var contentText: String? = nil
|
||||||
if contentHTML != nil && !(contentHTML!.contains("<")) {
|
if contentHTML != nil && !(contentHTML!.contains("<")) {
|
||||||
contentText = contentHTML
|
contentText = contentHTML
|
||||||
contentHTML = nil
|
contentHTML = nil
|
||||||
|
@ -77,9 +79,9 @@ private extension RSSInJSONParser {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var datePublished: Date = nil
|
var datePublished: Date? = nil
|
||||||
if let datePublishedString = itemDictionary["pubDate"] as? String {
|
if let datePublishedString = itemDictionary["pubDate"] as? String {
|
||||||
datePublished = RSDateWithString(datePublishedString as NSString)
|
datePublished = RSDateWithString(datePublishedString)
|
||||||
}
|
}
|
||||||
|
|
||||||
let authors = parseAuthors(itemDictionary)
|
let authors = parseAuthors(itemDictionary)
|
||||||
|
@ -112,14 +114,14 @@ private extension RSSInJSONParser {
|
||||||
}
|
}
|
||||||
if s.isEmpty {
|
if s.isEmpty {
|
||||||
// Sheesh. Tough case.
|
// Sheesh. Tough case.
|
||||||
if contentHTML != nil {
|
if let _ = contentHTML {
|
||||||
s = contentHTML
|
s = contentHTML!
|
||||||
}
|
}
|
||||||
if contentText != nil {
|
if let _ = contentText {
|
||||||
s = contentText
|
s = contentText!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uniqueID = (s as NSString).rsxml_md5HashString()
|
uniqueID = (s as NSString).rsparser_md5Hash()
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParsedItem(uniqueID: uniqueID, url: nil, externalURL: externalURL, title: title, contentHTML: contentHTML, contentText: contentText, summary: nil, imageURL: nil, bannerImageURL: nil, datePublished: datePublished, dateModified: nil, authors: authors, tags: tags, attachments: attachments)
|
return ParsedItem(uniqueID: uniqueID, url: nil, externalURL: externalURL, title: title, contentHTML: contentHTML, contentText: contentText, summary: nil, imageURL: nil, bannerImageURL: nil, datePublished: datePublished, dateModified: nil, authors: authors, tags: tags, attachments: attachments)
|
||||||
|
@ -137,11 +139,14 @@ private extension RSSInJSONParser {
|
||||||
static func parseTags(_ itemDictionary: JSONDictionary) -> [String]? {
|
static func parseTags(_ itemDictionary: JSONDictionary) -> [String]? {
|
||||||
|
|
||||||
if let categoryObject = itemDictionary["category"] as? JSONDictionary {
|
if let categoryObject = itemDictionary["category"] as? JSONDictionary {
|
||||||
return categoryObject["#value"]
|
if let oneTag = categoryObject["#value"] as? String {
|
||||||
|
return [oneTag]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
else if let categoryArray = itemDictionary["category"] as? JSONArray {
|
else if let categoryArray = itemDictionary["category"] as? JSONArray {
|
||||||
return categoryArray.flatMap{ (categoryObject) in
|
return categoryArray.flatMap{ (categoryObject) in
|
||||||
return categoryObject["#value"]
|
return categoryObject["#value"] as? String
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSAtomParser.h
|
// RSAtomParser.h
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 1/15/15.
|
// Created by Brent Simmons on 1/15/15.
|
||||||
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSAtomParser.m
|
// RSAtomParser.m
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 1/15/15.
|
// Created by Brent Simmons on 1/15/15.
|
||||||
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSFeedParser.h
|
// RSFeedParser.h
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 1/4/15.
|
// Created by Brent Simmons on 1/4/15.
|
||||||
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// FeedParser.m
|
// FeedParser.m
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 1/4/15.
|
// Created by Brent Simmons on 1/4/15.
|
||||||
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
||||||
|
|
|
@ -56,16 +56,16 @@
|
||||||
datePublishedTimeStampString = [NSString stringWithFormat:@"%.0f", self.datePublished.timeIntervalSince1970];
|
datePublishedTimeStampString = [NSString stringWithFormat:@"%.0f", self.datePublished.timeIntervalSince1970];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RSXMLStringIsEmpty(self.guid)) {
|
if (!RSParserStringIsEmpty(self.guid)) {
|
||||||
[s appendString:self.guid];
|
[s appendString:self.guid];
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!RSXMLStringIsEmpty(self.link) && self.datePublished != nil) {
|
else if (!RSParserStringIsEmpty(self.link) && self.datePublished != nil) {
|
||||||
[s appendString:self.link];
|
[s appendString:self.link];
|
||||||
[s appendString:datePublishedTimeStampString];
|
[s appendString:datePublishedTimeStampString];
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!RSXMLStringIsEmpty(self.title) && self.datePublished != nil) {
|
else if (!RSParserStringIsEmpty(self.title) && self.datePublished != nil) {
|
||||||
[s appendString:self.title];
|
[s appendString:self.title];
|
||||||
[s appendString:datePublishedTimeStampString];
|
[s appendString:datePublishedTimeStampString];
|
||||||
}
|
}
|
||||||
|
@ -74,19 +74,19 @@
|
||||||
[s appendString:datePublishedTimeStampString];
|
[s appendString:datePublishedTimeStampString];
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!RSXMLStringIsEmpty(self.link)) {
|
else if (!RSParserStringIsEmpty(self.link)) {
|
||||||
[s appendString:self.link];
|
[s appendString:self.link];
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!RSXMLStringIsEmpty(self.title)) {
|
else if (!RSParserStringIsEmpty(self.title)) {
|
||||||
[s appendString:self.title];
|
[s appendString:self.title];
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!RSXMLStringIsEmpty(self.body)) {
|
else if (!RSParserStringIsEmpty(self.body)) {
|
||||||
[s appendString:self.body];
|
[s appendString:self.body];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSAssert(!RSXMLStringIsEmpty(self.feedURL), nil);
|
NSAssert(!RSParserStringIsEmpty(self.feedURL), nil);
|
||||||
[s appendString:self.feedURL];
|
[s appendString:self.feedURL];
|
||||||
|
|
||||||
return [s rsxml_md5HashString];
|
return [s rsxml_md5HashString];
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSRSSParser.h
|
// RSRSSParser.h
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 1/6/15.
|
// Created by Brent Simmons on 1/6/15.
|
||||||
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSRSSParser.m
|
// RSRSSParser.m
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 1/6/15.
|
// Created by Brent Simmons on 1/6/15.
|
||||||
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
// Copyright (c) 2015 Ranchero Software LLC. All rights reserved.
|
||||||
|
@ -256,7 +256,7 @@ static const NSInteger kTrueLength = 5;
|
||||||
|
|
||||||
self.currentArticle.guid = self.parser.currentStringWithTrimmedWhitespace;
|
self.currentArticle.guid = self.parser.currentStringWithTrimmedWhitespace;
|
||||||
|
|
||||||
NSString *isPermaLinkValue = [self.currentAttributes rsxml_objectForCaseInsensitiveKey:@"ispermalink"];
|
NSString *isPermaLinkValue = [self.currentAttributes rsparser_objectForCaseInsensitiveKey:@"ispermalink"];
|
||||||
if (!isPermaLinkValue || ![isPermaLinkValue isEqualToString:@"false"]) {
|
if (!isPermaLinkValue || ![isPermaLinkValue isEqualToString:@"false"]) {
|
||||||
self.currentArticle.permalink = [self urlString:self.currentArticle.guid];
|
self.currentArticle.permalink = [self urlString:self.currentArticle.guid];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSHTMLLinkParser.h
|
// RSHTMLLinkParser.h
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 8/7/16.
|
// Created by Brent Simmons on 8/7/16.
|
||||||
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSHTMLLinkParser.m
|
// RSHTMLLinkParser.m
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 8/7/16.
|
// Created by Brent Simmons on 8/7/16.
|
||||||
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
@ -88,7 +88,7 @@ static NSString *kHrefKey = @"href";
|
||||||
|
|
||||||
- (NSString *)urlStringFromDictionary:(NSDictionary *)d {
|
- (NSString *)urlStringFromDictionary:(NSDictionary *)d {
|
||||||
|
|
||||||
NSString *href = [d rsxml_objectForCaseInsensitiveKey:kHrefKey];
|
NSString *href = [d rsparser_objectForCaseInsensitiveKey:kHrefKey];
|
||||||
if (!href) {
|
if (!href) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ static NSString *kTitleKey = @"title";
|
||||||
|
|
||||||
- (NSString *)titleFromDictionary:(NSDictionary *)d {
|
- (NSString *)titleFromDictionary:(NSDictionary *)d {
|
||||||
|
|
||||||
return [d rsxml_objectForCaseInsensitiveKey:kTitleKey];
|
return [d rsparser_objectForCaseInsensitiveKey:kTitleKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ static const NSInteger kAnchorLength = 2;
|
||||||
[self.links addObject:link];
|
[self.links addObject:link];
|
||||||
|
|
||||||
NSDictionary *d = [SAXParser attributesDictionary:attributes];
|
NSDictionary *d = [SAXParser attributesDictionary:attributes];
|
||||||
if (!RSXMLIsEmpty(d)) {
|
if (!RSParser_IsEmpty(d)) {
|
||||||
[self handleLinkAttributes:d];
|
[self handleLinkAttributes:d];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSHTMLMetadata.h
|
// RSHTMLMetadata.h
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 3/6/16.
|
// Created by Brent Simmons on 3/6/16.
|
||||||
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSHTMLMetadata.m
|
// RSHTMLMetadata.m
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 3/6/16.
|
// Created by Brent Simmons on 3/6/16.
|
||||||
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
@ -114,12 +114,12 @@ static NSString *kTypeKey = @"type";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString *oneType = [oneDictionary rsxml_objectForCaseInsensitiveKey:kTypeKey];
|
NSString *oneType = [oneDictionary rsparser_objectForCaseInsensitiveKey:kTypeKey];
|
||||||
if (!typeIsFeedType(oneType)) {
|
if (!typeIsFeedType(oneType)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RSXMLStringIsEmpty(urlStringFromDictionary(oneDictionary))) {
|
if (RSParserStringIsEmpty(urlStringFromDictionary(oneDictionary))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,18 +142,18 @@ static NSString *kTypeKey = @"type";
|
||||||
|
|
||||||
static NSString *relValue(NSDictionary *d) {
|
static NSString *relValue(NSDictionary *d) {
|
||||||
|
|
||||||
return [d rsxml_objectForCaseInsensitiveKey:kRelKey];
|
return [d rsparser_objectForCaseInsensitiveKey:kRelKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NSString *urlStringFromDictionary(NSDictionary *d) {
|
static NSString *urlStringFromDictionary(NSDictionary *d) {
|
||||||
|
|
||||||
NSString *urlString = [d rsxml_objectForCaseInsensitiveKey:kHrefKey];
|
NSString *urlString = [d rsparser_objectForCaseInsensitiveKey:kHrefKey];
|
||||||
if (urlString) {
|
if (urlString) {
|
||||||
return urlString;
|
return urlString;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [d rsxml_objectForCaseInsensitiveKey:kSrcKey];
|
return [d rsparser_objectForCaseInsensitiveKey:kSrcKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ static NSString *absoluteURLStringWithRelativeURLString(NSString *relativeURLStr
|
||||||
static NSString *absoluteURLStringWithDictionary(NSDictionary *d, NSString *baseURLString) {
|
static NSString *absoluteURLStringWithDictionary(NSDictionary *d, NSString *baseURLString) {
|
||||||
|
|
||||||
NSString *urlString = urlStringFromDictionary(d);
|
NSString *urlString = urlStringFromDictionary(d);
|
||||||
if (RSXMLStringIsEmpty(urlString)) {
|
if (RSParserStringIsEmpty(urlString)) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
return absoluteURLStringWithRelativeURLString(urlString, baseURLString);
|
return absoluteURLStringWithRelativeURLString(urlString, baseURLString);
|
||||||
|
@ -213,8 +213,8 @@ static BOOL typeIsFeedType(NSString *type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_urlString = absoluteURLStringWithDictionary(d, baseURLString);
|
_urlString = absoluteURLStringWithDictionary(d, baseURLString);
|
||||||
_sizes = [d rsxml_objectForCaseInsensitiveKey:kSizesKey];
|
_sizes = [d rsparser_objectForCaseInsensitiveKey:kSizesKey];
|
||||||
_rel = [d rsxml_objectForCaseInsensitiveKey:kRelKey];
|
_rel = [d rsparser_objectForCaseInsensitiveKey:kRelKey];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -234,8 +234,8 @@ static BOOL typeIsFeedType(NSString *type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_urlString = absoluteURLStringWithDictionary(d, baseURLString);
|
_urlString = absoluteURLStringWithDictionary(d, baseURLString);
|
||||||
_title = [d rsxml_objectForCaseInsensitiveKey:kTitleKey];
|
_title = [d rsparser_objectForCaseInsensitiveKey:kTitleKey];
|
||||||
_type = [d rsxml_objectForCaseInsensitiveKey:kTypeKey];
|
_type = [d rsparser_objectForCaseInsensitiveKey:kTypeKey];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSHTMLMetadataParser.h
|
// RSHTMLMetadataParser.h
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 3/6/16.
|
// Created by Brent Simmons on 3/6/16.
|
||||||
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
|
|
@ -76,21 +76,21 @@ static NSString *kRelKey = @"rel";
|
||||||
|
|
||||||
- (NSString *)linkForDictionary:(NSDictionary *)d {
|
- (NSString *)linkForDictionary:(NSDictionary *)d {
|
||||||
|
|
||||||
NSString *link = [d rsxml_objectForCaseInsensitiveKey:kHrefKey];
|
NSString *link = [d rsparser_objectForCaseInsensitiveKey:kHrefKey];
|
||||||
if (link) {
|
if (link) {
|
||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [d rsxml_objectForCaseInsensitiveKey:kSrcKey];
|
return [d rsparser_objectForCaseInsensitiveKey:kSrcKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)handleLinkAttributes:(NSDictionary *)d {
|
- (void)handleLinkAttributes:(NSDictionary *)d {
|
||||||
|
|
||||||
if (RSXMLStringIsEmpty([d rsxml_objectForCaseInsensitiveKey:kRelKey])) {
|
if (RSParserStringIsEmpty([d rsparser_objectForCaseInsensitiveKey:kRelKey])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (RSXMLStringIsEmpty([self linkForDictionary:d])) {
|
if (RSParserStringIsEmpty([self linkForDictionary:d])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ static const NSInteger kLinkLength = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSDictionary *d = [SAXParser attributesDictionary:attributes];
|
NSDictionary *d = [SAXParser attributesDictionary:attributes];
|
||||||
if (!RSXMLIsEmpty(d)) {
|
if (!RSParser_IsEmpty(d)) {
|
||||||
[self handleLinkAttributes:d];
|
[self handleLinkAttributes:d];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSSAXHTMLParser.h
|
// RSSAXHTMLParser.h
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 3/6/16.
|
// Created by Brent Simmons on 3/6/16.
|
||||||
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSSAXHTMLParser.m
|
// RSSAXHTMLParser.m
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 3/6/16.
|
// Created by Brent Simmons on 3/6/16.
|
||||||
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
@ -150,7 +150,7 @@ static xmlSAXHandler saxHandlerStruct;
|
||||||
- (NSString *)currentString {
|
- (NSString *)currentString {
|
||||||
|
|
||||||
NSData *d = self.currentCharacters;
|
NSData *d = self.currentCharacters;
|
||||||
if (RSXMLIsEmpty(d)) {
|
if (RSParserObjectIsEmpty(d)) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,43 +23,43 @@ NSString *OPMLXMLURLKey = @"xmlUrl";
|
||||||
|
|
||||||
- (NSString *)opml_text {
|
- (NSString *)opml_text {
|
||||||
|
|
||||||
return [self rsxml_objectForCaseInsensitiveKey:OPMLTextKey];
|
return [self rsparser_objectForCaseInsensitiveKey:OPMLTextKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (NSString *)opml_title {
|
- (NSString *)opml_title {
|
||||||
|
|
||||||
return [self rsxml_objectForCaseInsensitiveKey:OPMLTitleKey];
|
return [self rsparser_objectForCaseInsensitiveKey:OPMLTitleKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (NSString *)opml_description {
|
- (NSString *)opml_description {
|
||||||
|
|
||||||
return [self rsxml_objectForCaseInsensitiveKey:OPMLDescriptionKey];
|
return [self rsparser_objectForCaseInsensitiveKey:OPMLDescriptionKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (NSString *)opml_type {
|
- (NSString *)opml_type {
|
||||||
|
|
||||||
return [self rsxml_objectForCaseInsensitiveKey:OPMLTypeKey];
|
return [self rsparser_objectForCaseInsensitiveKey:OPMLTypeKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (NSString *)opml_version {
|
- (NSString *)opml_version {
|
||||||
|
|
||||||
return [self rsxml_objectForCaseInsensitiveKey:OPMLVersionKey];
|
return [self rsparser_objectForCaseInsensitiveKey:OPMLVersionKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (NSString *)opml_htmlUrl {
|
- (NSString *)opml_htmlUrl {
|
||||||
|
|
||||||
return [self rsxml_objectForCaseInsensitiveKey:OPMLHMTLURLKey];
|
return [self rsparser_objectForCaseInsensitiveKey:OPMLHMTLURLKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (NSString *)opml_xmlUrl {
|
- (NSString *)opml_xmlUrl {
|
||||||
|
|
||||||
return [self rsxml_objectForCaseInsensitiveKey:OPMLXMLURLKey];
|
return [self rsparser_objectForCaseInsensitiveKey:OPMLXMLURLKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,28 +14,28 @@
|
||||||
|
|
||||||
- (instancetype)initWithTitle:(NSString *)title feedDescription:(NSString *)feedDescription homePageURL:(NSString *)homePageURL feedURL:(NSString *)feedURL {
|
- (instancetype)initWithTitle:(NSString *)title feedDescription:(NSString *)feedDescription homePageURL:(NSString *)homePageURL feedURL:(NSString *)feedURL {
|
||||||
|
|
||||||
NSParameterAssert(!RSXMLIsEmpty(feedURL));
|
NSParameterAssert(!RSParserStringIsEmpty(feedURL));
|
||||||
|
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (!self) {
|
if (!self) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RSXMLIsEmpty(title)) {
|
if (RSParserStringIsEmpty(title)) {
|
||||||
_title = nil;
|
_title = nil;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_title = title;
|
_title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RSXMLIsEmpty(feedDescription)) {
|
if (RSParserStringIsEmpty(feedDescription)) {
|
||||||
_feedDescription = nil;
|
_feedDescription = nil;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_feedDescription = feedDescription;
|
_feedDescription = feedDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RSXMLIsEmpty(homePageURL)) {
|
if (RSParserStringIsEmpty(homePageURL)) {
|
||||||
_homePageURL = nil;
|
_homePageURL = nil;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString *feedURL = self.attributes.opml_xmlUrl;
|
NSString *feedURL = self.attributes.opml_xmlUrl;
|
||||||
if (RSXMLIsEmpty(feedURL)) {
|
if (RSParserObjectIsEmpty(feedURL)) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
@import Foundation;
|
@import Foundation;
|
||||||
|
|
||||||
#import <RSParser/NSData+RSParser.h>
|
#import <RSParser/NSData+RSParser.h>
|
||||||
#import <RSParser/RSParser.h>
|
#import <RSParser/RSDateParser.h>
|
||||||
|
#import <RSParser/NSString+RSParser.h>
|
||||||
|
|
||||||
//#import <RSXML/RSSAXParser.h>
|
//#import <RSXML/RSSAXParser.h>
|
||||||
//#import <RSXML/RSXMLData.h>
|
//#import <RSXML/RSXMLData.h>
|
||||||
|
|
|
@ -28,12 +28,12 @@
|
||||||
84469D0C1EFA307E004A6B28 /* RSHTMLMetadataParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D041EFA307E004A6B28 /* RSHTMLMetadataParser.m */; };
|
84469D0C1EFA307E004A6B28 /* RSHTMLMetadataParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D041EFA307E004A6B28 /* RSHTMLMetadataParser.m */; };
|
||||||
84469D0D1EFA307E004A6B28 /* RSSAXHTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D051EFA307E004A6B28 /* RSSAXHTMLParser.h */; };
|
84469D0D1EFA307E004A6B28 /* RSSAXHTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D051EFA307E004A6B28 /* RSSAXHTMLParser.h */; };
|
||||||
84469D0E1EFA307E004A6B28 /* RSSAXHTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D061EFA307E004A6B28 /* RSSAXHTMLParser.m */; };
|
84469D0E1EFA307E004A6B28 /* RSSAXHTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D061EFA307E004A6B28 /* RSSAXHTMLParser.m */; };
|
||||||
84469D161EFA30A2004A6B28 /* NSString+RSXML.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D101EFA30A2004A6B28 /* NSString+RSXML.h */; };
|
84469D161EFA30A2004A6B28 /* NSString+RSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D101EFA30A2004A6B28 /* NSString+RSParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
84469D171EFA30A2004A6B28 /* NSString+RSXML.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D111EFA30A2004A6B28 /* NSString+RSXML.m */; };
|
84469D171EFA30A2004A6B28 /* NSString+RSParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D111EFA30A2004A6B28 /* NSString+RSParser.m */; };
|
||||||
84469D181EFA30A2004A6B28 /* RSDateParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D121EFA30A2004A6B28 /* RSDateParser.h */; };
|
84469D181EFA30A2004A6B28 /* RSDateParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D121EFA30A2004A6B28 /* RSDateParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
84469D191EFA30A2004A6B28 /* RSDateParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D131EFA30A2004A6B28 /* RSDateParser.m */; };
|
84469D191EFA30A2004A6B28 /* RSDateParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D131EFA30A2004A6B28 /* RSDateParser.m */; };
|
||||||
84469D1A1EFA30A2004A6B28 /* RSXMLInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D141EFA30A2004A6B28 /* RSXMLInternal.h */; };
|
84469D1A1EFA30A2004A6B28 /* RSParserInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D141EFA30A2004A6B28 /* RSParserInternal.h */; };
|
||||||
84469D1B1EFA30A2004A6B28 /* RSXMLInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D151EFA30A2004A6B28 /* RSXMLInternal.m */; };
|
84469D1B1EFA30A2004A6B28 /* RSParserInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D151EFA30A2004A6B28 /* RSParserInternal.m */; };
|
||||||
84469D271EFA3134004A6B28 /* RSAtomParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D1D1EFA3134004A6B28 /* RSAtomParser.h */; };
|
84469D271EFA3134004A6B28 /* RSAtomParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D1D1EFA3134004A6B28 /* RSAtomParser.h */; };
|
||||||
84469D281EFA3134004A6B28 /* RSAtomParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D1E1EFA3134004A6B28 /* RSAtomParser.m */; };
|
84469D281EFA3134004A6B28 /* RSAtomParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D1E1EFA3134004A6B28 /* RSAtomParser.m */; };
|
||||||
84469D291EFA3134004A6B28 /* RSFeedParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D1F1EFA3134004A6B28 /* RSFeedParser.h */; };
|
84469D291EFA3134004A6B28 /* RSFeedParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D1F1EFA3134004A6B28 /* RSFeedParser.h */; };
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
84469D2F1EFA3134004A6B28 /* RSRSSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D251EFA3134004A6B28 /* RSRSSParser.h */; };
|
84469D2F1EFA3134004A6B28 /* RSRSSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D251EFA3134004A6B28 /* RSRSSParser.h */; };
|
||||||
84469D301EFA3134004A6B28 /* RSRSSParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D261EFA3134004A6B28 /* RSRSSParser.m */; };
|
84469D301EFA3134004A6B28 /* RSRSSParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D261EFA3134004A6B28 /* RSRSSParser.m */; };
|
||||||
84469D321EFA31CF004A6B28 /* FeedParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84469D311EFA31CF004A6B28 /* FeedParser.swift */; };
|
84469D321EFA31CF004A6B28 /* FeedParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84469D311EFA31CF004A6B28 /* FeedParser.swift */; };
|
||||||
84469D351EFF1190004A6B28 /* NSData+RSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D331EFF1190004A6B28 /* NSData+RSParser.h */; };
|
84469D351EFF1190004A6B28 /* NSData+RSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84469D331EFF1190004A6B28 /* NSData+RSParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
84469D361EFF1190004A6B28 /* NSData+RSParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D341EFF1190004A6B28 /* NSData+RSParser.m */; };
|
84469D361EFF1190004A6B28 /* NSData+RSParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 84469D341EFF1190004A6B28 /* NSData+RSParser.m */; };
|
||||||
84469D381EFF2645004A6B28 /* RSSInJSONParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84469D371EFF2645004A6B28 /* RSSInJSONParser.swift */; };
|
84469D381EFF2645004A6B28 /* RSSInJSONParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84469D371EFF2645004A6B28 /* RSSInJSONParser.swift */; };
|
||||||
84469D401EFF29A9004A6B28 /* FeedParserError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84469D3F1EFF29A9004A6B28 /* FeedParserError.swift */; };
|
84469D401EFF29A9004A6B28 /* FeedParserError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84469D3F1EFF29A9004A6B28 /* FeedParserError.swift */; };
|
||||||
|
@ -94,12 +94,12 @@
|
||||||
84469D041EFA307E004A6B28 /* RSHTMLMetadataParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSHTMLMetadataParser.m; sourceTree = "<group>"; };
|
84469D041EFA307E004A6B28 /* RSHTMLMetadataParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSHTMLMetadataParser.m; sourceTree = "<group>"; };
|
||||||
84469D051EFA307E004A6B28 /* RSSAXHTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSAXHTMLParser.h; sourceTree = "<group>"; };
|
84469D051EFA307E004A6B28 /* RSSAXHTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSAXHTMLParser.h; sourceTree = "<group>"; };
|
||||||
84469D061EFA307E004A6B28 /* RSSAXHTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSAXHTMLParser.m; sourceTree = "<group>"; };
|
84469D061EFA307E004A6B28 /* RSSAXHTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSAXHTMLParser.m; sourceTree = "<group>"; };
|
||||||
84469D101EFA30A2004A6B28 /* NSString+RSXML.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+RSXML.h"; sourceTree = "<group>"; };
|
84469D101EFA30A2004A6B28 /* NSString+RSParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+RSParser.h"; sourceTree = "<group>"; };
|
||||||
84469D111EFA30A2004A6B28 /* NSString+RSXML.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+RSXML.m"; sourceTree = "<group>"; };
|
84469D111EFA30A2004A6B28 /* NSString+RSParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+RSParser.m"; sourceTree = "<group>"; };
|
||||||
84469D121EFA30A2004A6B28 /* RSDateParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDateParser.h; sourceTree = "<group>"; };
|
84469D121EFA30A2004A6B28 /* RSDateParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RSDateParser.h; path = Utilities/RSDateParser.h; sourceTree = "<group>"; };
|
||||||
84469D131EFA30A2004A6B28 /* RSDateParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDateParser.m; sourceTree = "<group>"; };
|
84469D131EFA30A2004A6B28 /* RSDateParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RSDateParser.m; path = Utilities/RSDateParser.m; sourceTree = "<group>"; };
|
||||||
84469D141EFA30A2004A6B28 /* RSXMLInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSXMLInternal.h; sourceTree = "<group>"; };
|
84469D141EFA30A2004A6B28 /* RSParserInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSParserInternal.h; sourceTree = "<group>"; };
|
||||||
84469D151EFA30A2004A6B28 /* RSXMLInternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSXMLInternal.m; sourceTree = "<group>"; };
|
84469D151EFA30A2004A6B28 /* RSParserInternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSParserInternal.m; sourceTree = "<group>"; };
|
||||||
84469D1D1EFA3134004A6B28 /* RSAtomParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSAtomParser.h; sourceTree = "<group>"; };
|
84469D1D1EFA3134004A6B28 /* RSAtomParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSAtomParser.h; sourceTree = "<group>"; };
|
||||||
84469D1E1EFA3134004A6B28 /* RSAtomParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSAtomParser.m; sourceTree = "<group>"; };
|
84469D1E1EFA3134004A6B28 /* RSAtomParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSAtomParser.m; sourceTree = "<group>"; };
|
||||||
84469D1F1EFA3134004A6B28 /* RSFeedParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSFeedParser.h; sourceTree = "<group>"; };
|
84469D1F1EFA3134004A6B28 /* RSFeedParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSFeedParser.h; sourceTree = "<group>"; };
|
||||||
|
@ -150,6 +150,15 @@
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
84285AA61F004879002E8708 /* Dates */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
84469D121EFA30A2004A6B28 /* RSDateParser.h */,
|
||||||
|
84469D131EFA30A2004A6B28 /* RSDateParser.m */,
|
||||||
|
);
|
||||||
|
name = Dates;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
84469CE31EFA2FB0004A6B28 /* Feeds */ = {
|
84469CE31EFA2FB0004A6B28 /* Feeds */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -213,12 +222,10 @@
|
||||||
children = (
|
children = (
|
||||||
84469D331EFF1190004A6B28 /* NSData+RSParser.h */,
|
84469D331EFF1190004A6B28 /* NSData+RSParser.h */,
|
||||||
84469D341EFF1190004A6B28 /* NSData+RSParser.m */,
|
84469D341EFF1190004A6B28 /* NSData+RSParser.m */,
|
||||||
84469D101EFA30A2004A6B28 /* NSString+RSXML.h */,
|
84469D101EFA30A2004A6B28 /* NSString+RSParser.h */,
|
||||||
84469D111EFA30A2004A6B28 /* NSString+RSXML.m */,
|
84469D111EFA30A2004A6B28 /* NSString+RSParser.m */,
|
||||||
84469D121EFA30A2004A6B28 /* RSDateParser.h */,
|
84469D141EFA30A2004A6B28 /* RSParserInternal.h */,
|
||||||
84469D131EFA30A2004A6B28 /* RSDateParser.m */,
|
84469D151EFA30A2004A6B28 /* RSParserInternal.m */,
|
||||||
84469D141EFA30A2004A6B28 /* RSXMLInternal.h */,
|
|
||||||
84469D151EFA30A2004A6B28 /* RSXMLInternal.m */,
|
|
||||||
);
|
);
|
||||||
path = Utilities;
|
path = Utilities;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -257,6 +264,7 @@
|
||||||
84D81BDA1EFA28E700652332 /* RSParser.h */,
|
84D81BDA1EFA28E700652332 /* RSParser.h */,
|
||||||
84469CE11EFA2F3E004A6B28 /* ParserData.swift */,
|
84469CE11EFA2F3E004A6B28 /* ParserData.swift */,
|
||||||
84469CE31EFA2FB0004A6B28 /* Feeds */,
|
84469CE31EFA2FB0004A6B28 /* Feeds */,
|
||||||
|
84285AA61F004879002E8708 /* Dates */,
|
||||||
84469CE41EFA3000004A6B28 /* OPML */,
|
84469CE41EFA3000004A6B28 /* OPML */,
|
||||||
84469CFE1EFA307E004A6B28 /* HTML */,
|
84469CFE1EFA307E004A6B28 /* HTML */,
|
||||||
84469CF91EFA3069004A6B28 /* SAX */,
|
84469CF91EFA3069004A6B28 /* SAX */,
|
||||||
|
@ -298,7 +306,7 @@
|
||||||
84469CF51EFA3000004A6B28 /* RSOPMLItem.h in Headers */,
|
84469CF51EFA3000004A6B28 /* RSOPMLItem.h in Headers */,
|
||||||
84469D2D1EFA3134004A6B28 /* RSParsedFeed.h in Headers */,
|
84469D2D1EFA3134004A6B28 /* RSParsedFeed.h in Headers */,
|
||||||
84469D181EFA30A2004A6B28 /* RSDateParser.h in Headers */,
|
84469D181EFA30A2004A6B28 /* RSDateParser.h in Headers */,
|
||||||
84469D1A1EFA30A2004A6B28 /* RSXMLInternal.h in Headers */,
|
84469D1A1EFA30A2004A6B28 /* RSParserInternal.h in Headers */,
|
||||||
84469D351EFF1190004A6B28 /* NSData+RSParser.h in Headers */,
|
84469D351EFF1190004A6B28 /* NSData+RSParser.h in Headers */,
|
||||||
84D81BDC1EFA28E700652332 /* RSParser.h in Headers */,
|
84D81BDC1EFA28E700652332 /* RSParser.h in Headers */,
|
||||||
84469D0B1EFA307E004A6B28 /* RSHTMLMetadataParser.h in Headers */,
|
84469D0B1EFA307E004A6B28 /* RSHTMLMetadataParser.h in Headers */,
|
||||||
|
@ -311,7 +319,7 @@
|
||||||
84469CF31EFA3000004A6B28 /* RSOPMLFeedSpecifier.h in Headers */,
|
84469CF31EFA3000004A6B28 /* RSOPMLFeedSpecifier.h in Headers */,
|
||||||
84469CF11EFA3000004A6B28 /* RSOPMLDocument.h in Headers */,
|
84469CF11EFA3000004A6B28 /* RSOPMLDocument.h in Headers */,
|
||||||
84469D091EFA307E004A6B28 /* RSHTMLMetadata.h in Headers */,
|
84469D091EFA307E004A6B28 /* RSHTMLMetadata.h in Headers */,
|
||||||
84469D161EFA30A2004A6B28 /* NSString+RSXML.h in Headers */,
|
84469D161EFA30A2004A6B28 /* NSString+RSParser.h in Headers */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -414,7 +422,7 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
84469D081EFA307E004A6B28 /* RSHTMLLinkParser.m in Sources */,
|
84469D081EFA307E004A6B28 /* RSHTMLLinkParser.m in Sources */,
|
||||||
84469D1B1EFA30A2004A6B28 /* RSXMLInternal.m in Sources */,
|
84469D1B1EFA30A2004A6B28 /* RSParserInternal.m in Sources */,
|
||||||
84D81BE21EFA2D0900652332 /* ParsedAuthor.swift in Sources */,
|
84D81BE21EFA2D0900652332 /* ParsedAuthor.swift in Sources */,
|
||||||
84469D0E1EFA307E004A6B28 /* RSSAXHTMLParser.m in Sources */,
|
84469D0E1EFA307E004A6B28 /* RSSAXHTMLParser.m in Sources */,
|
||||||
84469CF41EFA3000004A6B28 /* RSOPMLFeedSpecifier.m in Sources */,
|
84469CF41EFA3000004A6B28 /* RSOPMLFeedSpecifier.m in Sources */,
|
||||||
|
@ -431,7 +439,7 @@
|
||||||
84469D421EFF2B2D004A6B28 /* JSONTypes.swift in Sources */,
|
84469D421EFF2B2D004A6B28 /* JSONTypes.swift in Sources */,
|
||||||
84469D0C1EFA307E004A6B28 /* RSHTMLMetadataParser.m in Sources */,
|
84469D0C1EFA307E004A6B28 /* RSHTMLMetadataParser.m in Sources */,
|
||||||
84469D0A1EFA307E004A6B28 /* RSHTMLMetadata.m in Sources */,
|
84469D0A1EFA307E004A6B28 /* RSHTMLMetadata.m in Sources */,
|
||||||
84469D171EFA30A2004A6B28 /* NSString+RSXML.m in Sources */,
|
84469D171EFA30A2004A6B28 /* NSString+RSParser.m in Sources */,
|
||||||
84469D2C1EFA3134004A6B28 /* RSParsedArticle.m in Sources */,
|
84469D2C1EFA3134004A6B28 /* RSParsedArticle.m in Sources */,
|
||||||
84469D2E1EFA3134004A6B28 /* RSParsedFeed.m in Sources */,
|
84469D2E1EFA3134004A6B28 /* RSParsedFeed.m in Sources */,
|
||||||
84469CF81EFA3000004A6B28 /* RSOPMLParser.m in Sources */,
|
84469CF81EFA3000004A6B28 /* RSOPMLParser.m in Sources */,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSSAXParser.h
|
// RSSAXParser.h
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 3/25/15.
|
// Created by Brent Simmons on 3/25/15.
|
||||||
// Copyright (c) 2015 Ranchero Software, LLC. All rights reserved.
|
// Copyright (c) 2015 Ranchero Software, LLC. All rights reserved.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSSAXParser.m
|
// RSSAXParser.m
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 3/25/15.
|
// Created by Brent Simmons on 3/25/15.
|
||||||
// Copyright (c) 2015 Ranchero Software, LLC. All rights reserved.
|
// Copyright (c) 2015 Ranchero Software, LLC. All rights reserved.
|
||||||
|
@ -152,7 +152,7 @@ static xmlSAXHandler saxHandlerStruct;
|
||||||
- (NSString *)currentString {
|
- (NSString *)currentString {
|
||||||
|
|
||||||
NSData *d = self.currentCharacters;
|
NSData *d = self.currentCharacters;
|
||||||
if (RSXMLIsEmpty(d)) {
|
if (RSParserObjectIsEmpty(d)) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,11 @@
|
||||||
- (BOOL)isProbablyXML;
|
- (BOOL)isProbablyXML;
|
||||||
- (BOOL)isProbablyJSON;
|
- (BOOL)isProbablyJSON;
|
||||||
|
|
||||||
|
- (BOOL)isProbablyJSONFeed;
|
||||||
|
- (BOOL)isProbablyRSSInJSON;
|
||||||
|
- (BOOL)isProbablyRSS;
|
||||||
|
- (BOOL)isProbablyAtom;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ static BOOL bytesStartWithStringIgnoringWhitespace(const char *string, const cha
|
||||||
return didFindString("https://jsonfeed.org/version/", self.bytes, self.length);
|
return didFindString("https://jsonfeed.org/version/", self.bytes, self.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isProbablyRSSInJSONFeed {
|
- (BOOL)isProbablyRSSInJSON {
|
||||||
|
|
||||||
if (![self isProbablyJSON]) {
|
if (![self isProbablyJSON]) {
|
||||||
return NO;
|
return NO;
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
//
|
||||||
|
// NSString+RSParser.h
|
||||||
|
// RSParser
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 9/25/15.
|
||||||
|
// Copyright © 2015 Ranchero Software, LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
@import Foundation;
|
||||||
|
|
||||||
|
@interface NSString (RSParser)
|
||||||
|
|
||||||
|
- (NSString *)rsparser_stringByDecodingHTMLEntities;
|
||||||
|
|
||||||
|
- (NSString *)rsparser_md5Hash;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
//
|
//
|
||||||
// NSString+RSXML.m
|
// NSString+RSParser.m
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 9/25/15.
|
// Created by Brent Simmons on 9/25/15.
|
||||||
// Copyright © 2015 Ranchero Software, LLC. All rights reserved.
|
// Copyright © 2015 Ranchero Software, LLC. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "NSString+RSXML.h"
|
#import "NSString+RSParser.h"
|
||||||
|
|
||||||
|
|
||||||
@interface NSScanner (RSXML)
|
@interface NSScanner (RSParser)
|
||||||
|
|
||||||
- (BOOL)rs_scanEntityValue:(NSString * _Nullable * _Nullable)decodedEntity;
|
- (BOOL)rs_scanEntityValue:(NSString * _Nullable * _Nullable)decodedEntity;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
@implementation NSString (RSXML)
|
@implementation NSString (RSParser)
|
||||||
|
|
||||||
- (NSString *)rs_stringByDecodingHTMLEntities {
|
- (NSString *)rsparser_stringByDecodingHTMLEntities {
|
||||||
|
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
|
|
||||||
|
|
||||||
static NSDictionary *RSEntitiesDictionary(void);
|
static NSDictionary *RSEntitiesDictionary(void);
|
||||||
static NSString *RSXMLStringWithValue(unichar value);
|
static NSString *RSParserStringWithValue(unichar value);
|
||||||
|
|
||||||
- (NSString * _Nullable)rs_stringByDecodingEntity {
|
- (NSString * _Nullable)rs_stringByDecodingEntity {
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ static NSString *RSXMLStringWithValue(unichar value);
|
||||||
scanner.charactersToBeSkipped = [NSCharacterSet characterSetWithCharactersInString:@"#x"];
|
scanner.charactersToBeSkipped = [NSCharacterSet characterSetWithCharactersInString:@"#x"];
|
||||||
unsigned int hexValue = 0;
|
unsigned int hexValue = 0;
|
||||||
if ([scanner scanHexInt:&hexValue]) {
|
if ([scanner scanHexInt:&hexValue]) {
|
||||||
return RSXMLStringWithValue((unichar)hexValue);
|
return RSParserStringWithValue((unichar)hexValue);
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -98,15 +98,33 @@ static NSString *RSXMLStringWithValue(unichar value);
|
||||||
if (value < 1) {
|
if (value < 1) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
return RSXMLStringWithValue((unichar)value);
|
return RSParserStringWithValue((unichar)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSData *)_rsparser_md5HashData {
|
||||||
|
|
||||||
|
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
unsigned char hash[CC_MD5_DIGEST_LENGTH];
|
||||||
|
CC_MD5(data.bytes, (CC_LONG)data.length, hash);
|
||||||
|
|
||||||
|
return [NSData dataWithBytes:(const void *)hash length:CC_MD5_DIGEST_LENGTH];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)rsparser_md5Hash {
|
||||||
|
|
||||||
|
NSData *md5Data = [self _rsparser_md5HashData];
|
||||||
|
const Byte *bytes = md5Data.bytes;
|
||||||
|
return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation NSScanner (RSXML)
|
@implementation NSScanner (RSParser)
|
||||||
|
|
||||||
- (BOOL)rs_scanEntityValue:(NSString * _Nullable * _Nullable)decodedEntity {
|
- (BOOL)rs_scanEntityValue:(NSString * _Nullable * _Nullable)decodedEntity {
|
||||||
|
|
||||||
|
@ -144,7 +162,7 @@ static NSString *RSXMLStringWithValue(unichar value);
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
static NSString *RSXMLStringWithValue(unichar value) {
|
static NSString *RSParserStringWithValue(unichar value) {
|
||||||
|
|
||||||
return [[NSString alloc] initWithFormat:@"%C", value];
|
return [[NSString alloc] initWithFormat:@"%C", value];
|
||||||
}
|
}
|
||||||
|
@ -169,7 +187,7 @@ static NSDictionary *RSEntitiesDictionary(void) {
|
||||||
@"#150": @"-",
|
@"#150": @"-",
|
||||||
@"#151": @"—",
|
@"#151": @"—",
|
||||||
@"#153": @"™",
|
@"#153": @"™",
|
||||||
@"#160": RSXMLStringWithValue(160),
|
@"#160": RSParserStringWithValue(160),
|
||||||
@"#161": @"¡",
|
@"#161": @"¡",
|
||||||
@"#162": @"¢",
|
@"#162": @"¢",
|
||||||
@"#163": @"£",
|
@"#163": @"£",
|
||||||
|
@ -277,7 +295,7 @@ static NSDictionary *RSEntitiesDictionary(void) {
|
||||||
@"#8220": @"“",
|
@"#8220": @"“",
|
||||||
@"#8221": @"”",
|
@"#8221": @"”",
|
||||||
@"#8230": @"…",
|
@"#8230": @"…",
|
||||||
@"#8617": RSXMLStringWithValue(8617),
|
@"#8617": RSParserStringWithValue(8617),
|
||||||
@"AElig": @"Æ",
|
@"AElig": @"Æ",
|
||||||
@"Aacute": @"Á",
|
@"Aacute": @"Á",
|
||||||
@"Acirc": @"Â",
|
@"Acirc": @"Â",
|
||||||
|
@ -394,14 +412,14 @@ static NSDictionary *RSEntitiesDictionary(void) {
|
||||||
@"yen": @"¥",
|
@"yen": @"¥",
|
||||||
@"yuml": @"ÿ",
|
@"yuml": @"ÿ",
|
||||||
@"infin": @"∞",
|
@"infin": @"∞",
|
||||||
@"nbsp": RSXMLStringWithValue(160),
|
@"nbsp": RSParserStringWithValue(160),
|
||||||
@"#x21A9": RSXMLStringWithValue(8617),
|
@"#x21A9": RSParserStringWithValue(8617),
|
||||||
@"#xFE0E": RSXMLStringWithValue(65038),
|
@"#xFE0E": RSParserStringWithValue(65038),
|
||||||
@"#x2019": RSXMLStringWithValue(8217),
|
@"#x2019": RSParserStringWithValue(8217),
|
||||||
@"#x2026": RSXMLStringWithValue(8230),
|
@"#x2026": RSParserStringWithValue(8230),
|
||||||
@"#x201C": RSXMLStringWithValue(8220),
|
@"#x201C": RSParserStringWithValue(8220),
|
||||||
@"#x201D": RSXMLStringWithValue(8221),
|
@"#x201D": RSParserStringWithValue(8221),
|
||||||
@"#x2014": RSXMLStringWithValue(8212)};
|
@"#x2014": RSParserStringWithValue(8212)};
|
||||||
});
|
});
|
||||||
|
|
||||||
return entitiesDictionary;
|
return entitiesDictionary;
|
|
@ -1,16 +0,0 @@
|
||||||
//
|
|
||||||
// NSString+RSXML.h
|
|
||||||
// RSXML
|
|
||||||
//
|
|
||||||
// Created by Brent Simmons on 9/25/15.
|
|
||||||
// Copyright © 2015 Ranchero Software, LLC. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
@import Foundation;
|
|
||||||
|
|
||||||
@interface NSString (RSXML)
|
|
||||||
|
|
||||||
- (NSString *)rs_stringByDecodingHTMLEntities;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSDateParser.h
|
// RSDateParser.h
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 3/25/15.
|
// Created by Brent Simmons on 3/25/15.
|
||||||
// Copyright (c) 2015 Ranchero Software, LLC. All rights reserved.
|
// Copyright (c) 2015 Ranchero Software, LLC. All rights reserved.
|
||||||
|
@ -9,17 +9,14 @@
|
||||||
@import Foundation;
|
@import Foundation;
|
||||||
|
|
||||||
|
|
||||||
/*Common web dates -- RFC 822 and 8601 -- are handled here:
|
// Common web dates -- RFC 822 and 8601 -- are handled here: the formats you find in JSON and XML feeds.
|
||||||
the formats you find in JSON and XML feeds.
|
// These may return nil. They may also return garbage, given bad input.
|
||||||
|
|
||||||
Any of these may return nil. They may also return garbage, given bad input.*/
|
|
||||||
|
|
||||||
|
|
||||||
NSDate *RSDateWithString(NSString *dateString);
|
NSDate *RSDateWithString(NSString *dateString);
|
||||||
|
|
||||||
/*If you're using a SAX parser, you have the bytes and don't need to convert to a string first.
|
// If you're using a SAX parser, you have the bytes and don't need to convert to a string first.
|
||||||
It's faster and uses less memory.
|
// It's faster and uses less memory.
|
||||||
(Assumes bytes are UTF-8 or ASCII. If you're using the libxml SAX parser, this will work.)*/
|
// (Assumes bytes are UTF-8 or ASCII. If you're using the libxml SAX parser, this will work.)
|
||||||
|
|
||||||
NSDate *RSDateWithBytes(const char *bytes, NSUInteger numberOfBytes);
|
NSDate *RSDateWithBytes(const char *bytes, NSUInteger numberOfBytes);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// RSDateParser.m
|
// RSDateParser.m
|
||||||
// RSXML
|
// RSParser
|
||||||
//
|
//
|
||||||
// Created by Brent Simmons on 3/25/15.
|
// Created by Brent Simmons on 3/25/15.
|
||||||
// Copyright (c) 2015 Ranchero Software, LLC. All rights reserved.
|
// Copyright (c) 2015 Ranchero Software, LLC. All rights reserved.
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
//
|
||||||
|
// RSParserInternal.h
|
||||||
|
// RSParser
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 12/26/16.
|
||||||
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
@import Foundation;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
BOOL RSParser_IsEmpty(id _Nullable obj);
|
||||||
|
BOOL RSParserStringIsEmpty(NSString * _Nullable s);
|
||||||
|
|
||||||
|
|
||||||
|
@interface NSDictionary (RSParserInternal)
|
||||||
|
|
||||||
|
- (nullable id)rsparser_objectForCaseInsensitiveKey:(NSString *)key;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
//
|
||||||
|
// RSXMLInternal.m
|
||||||
|
// RSParser
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 12/26/16.
|
||||||
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <CommonCrypto/CommonDigest.h>
|
||||||
|
#import "RSXMLInternal.h"
|
||||||
|
|
||||||
|
|
||||||
|
static BOOL RSParserIsNil(id obj) {
|
||||||
|
|
||||||
|
return obj == nil || obj == [NSNull null];
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL RSParserObjectIsEmpty(id obj) {
|
||||||
|
|
||||||
|
if (RSParserIsNil(obj)) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([obj respondsToSelector:@selector(count)]) {
|
||||||
|
return [obj count] < 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([obj respondsToSelector:@selector(length)]) {
|
||||||
|
return [obj length] < 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO; /*Shouldn't get here very often.*/
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL RSParserStringIsEmpty(NSString *s) {
|
||||||
|
|
||||||
|
return RSParserIsNil(s) || s.length < 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@implementation NSDictionary (RSParserInternal)
|
||||||
|
|
||||||
|
- (nullable id)rsparser_objectForCaseInsensitiveKey:(NSString *)key {
|
||||||
|
|
||||||
|
id obj = self[key];
|
||||||
|
if (obj) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NSString *oneKey in self.allKeys) {
|
||||||
|
|
||||||
|
if ([oneKey isKindOfClass:[NSString class]] && [key caseInsensitiveCompare:oneKey] == NSOrderedSame) {
|
||||||
|
return self[oneKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -1,31 +0,0 @@
|
||||||
//
|
|
||||||
// RSXMLInternal.h
|
|
||||||
// RSXML
|
|
||||||
//
|
|
||||||
// Created by Brent Simmons on 12/26/16.
|
|
||||||
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
@import Foundation;
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
BOOL RSXMLIsEmpty(id _Nullable obj);
|
|
||||||
BOOL RSXMLStringIsEmpty(NSString * _Nullable s);
|
|
||||||
|
|
||||||
|
|
||||||
@interface NSString (RSXMLInternal)
|
|
||||||
|
|
||||||
- (NSString *)rsxml_md5HashString;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
@interface NSDictionary (RSXMLInternal)
|
|
||||||
|
|
||||||
- (nullable id)rsxml_objectForCaseInsensitiveKey:(NSString *)key;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
//
|
|
||||||
// RSXMLInternal.m
|
|
||||||
// RSXML
|
|
||||||
//
|
|
||||||
// Created by Brent Simmons on 12/26/16.
|
|
||||||
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <CommonCrypto/CommonDigest.h>
|
|
||||||
#import "RSXMLInternal.h"
|
|
||||||
|
|
||||||
|
|
||||||
static BOOL RSXMLIsNil(id obj) {
|
|
||||||
|
|
||||||
return obj == nil || obj == [NSNull null];
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL RSXMLIsEmpty(id obj) {
|
|
||||||
|
|
||||||
if (RSXMLIsNil(obj)) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([obj respondsToSelector:@selector(count)]) {
|
|
||||||
return [obj count] < 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([obj respondsToSelector:@selector(length)]) {
|
|
||||||
return [obj length] < 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NO; /*Shouldn't get here very often.*/
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL RSXMLStringIsEmpty(NSString *s) {
|
|
||||||
|
|
||||||
return RSXMLIsNil(s) || s.length < 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@implementation NSString (RSXMLInternal)
|
|
||||||
|
|
||||||
- (NSData *)rsxml_md5Hash {
|
|
||||||
|
|
||||||
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
unsigned char hash[CC_MD5_DIGEST_LENGTH];
|
|
||||||
CC_MD5(data.bytes, (CC_LONG)data.length, hash);
|
|
||||||
|
|
||||||
return [NSData dataWithBytes:(const void *)hash length:CC_MD5_DIGEST_LENGTH];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)rsxml_md5HashString {
|
|
||||||
|
|
||||||
NSData *md5Data = [self rsxml_md5Hash];
|
|
||||||
const Byte *bytes = md5Data.bytes;
|
|
||||||
return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
@implementation NSDictionary (RSXMLInternal)
|
|
||||||
|
|
||||||
|
|
||||||
- (nullable id)rsxml_objectForCaseInsensitiveKey:(NSString *)key {
|
|
||||||
|
|
||||||
id obj = self[key];
|
|
||||||
if (obj) {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (NSString *oneKey in self.allKeys) {
|
|
||||||
|
|
||||||
if ([oneKey isKindOfClass:[NSString class]] && [key caseInsensitiveCompare:oneKey] == NSOrderedSame) {
|
|
||||||
return self[oneKey];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
|
Loading…
Reference in New Issue