diff --git a/Frameworks/RSParser/Feeds/JSON/JSONFeedParser.swift b/Frameworks/RSParser/Feeds/JSON/JSONFeedParser.swift index c77c9dc58..166898af4 100644 --- a/Frameworks/RSParser/Feeds/JSON/JSONFeedParser.swift +++ b/Frameworks/RSParser/Feeds/JSON/JSONFeedParser.swift @@ -134,7 +134,7 @@ private extension JSONFeedParser { let url = itemDictionary[Key.url] as? String let externalURL = itemDictionary[Key.externalURL] as? String - let title = itemDictionary[Key.title] as? String + let title = parseTitle(itemDictionary, feedURL) let summary = itemDictionary[Key.summary] as? String let imageURL = itemDictionary[Key.image] as? String let bannerImageURL = itemDictionary[Key.bannerImage] as? String @@ -152,6 +152,35 @@ private extension JSONFeedParser { return ParsedItem(syncServiceID: nil, uniqueID: uniqueID, feedURL: feedURL, url: url, externalURL: externalURL, title: title, contentHTML: decodedContentHTML, contentText: contentText, summary: summary, imageURL: imageURL, bannerImageURL: bannerImageURL, datePublished: datePublished, dateModified: dateModified, authors: authors, tags: tags, attachments: attachments) } + static func parseTitle(_ itemDictionary: JSONDictionary, _ feedURL: String) -> String? { + + guard let title = itemDictionary[Key.title] as? String else { + return nil + } + + if isSpecialCaseTitleWithEntitiesFeed(feedURL) { + return (title as NSString).rsparser_stringByDecodingHTMLEntities() + } + + return title + } + + static func isSpecialCaseTitleWithEntitiesFeed(_ feedURL: String) -> Bool { + + // As of 16 Feb. 2018, Kottke’s and Heer’s feeds includes HTML entities in the title elements. + // If we find more feeds like this, we’ll add them here. If these feeds get fixed, we’ll remove them. + + let lowerFeedURL = feedURL.lowercased() + let matchStrings = ["kottke.org", "pxlnv.com"] + for matchString in matchStrings { + if lowerFeedURL.contains(matchString) { + return true + } + } + + return false + } + static func parseUniqueID(_ itemDictionary: JSONDictionary) -> String? { if let uniqueID = itemDictionary[Key.uniqueID] as? String {