diff --git a/Evergreen/Favicons/FaviconURLFinder.swift b/Evergreen/Favicons/FaviconURLFinder.swift index fe0324e89..c29b938aa 100644 --- a/Evergreen/Favicons/FaviconURLFinder.swift +++ b/Evergreen/Favicons/FaviconURLFinder.swift @@ -8,64 +8,20 @@ import Foundation import RSParser -import RSWeb -import RSCore // The favicon URL may be specified in the head section of the home page. struct FaviconURLFinder { - static var metadataCache = [String: RSHTMLMetadata]() - static let serialDispatchQueue = DispatchQueue(label: "FaviconURLFinder") - static func findFaviconURL(_ homePageURL: String, _ callback: @escaping (String?) -> Void) { - guard let url = URL(string: homePageURL) else { + guard let _ = URL(string: homePageURL) else { callback(nil) return } - downloadUsingCache(url) { (data, response, error) in - - guard let data = data, let response = response, response.statusIsOK else { - callback(nil) - return - } - - // Use the absoluteString of the response’s URL instead of the homePageURL, - // since the homePageURL might actually have been redirected. - // Example: Dr. Drang’s feed reports the homePageURL as http://www.leancrew.com/all-this — - // but it gets redirected to http://www.leancrew.com/all-this/ — which is correct. - // This way any relative link to a favicon in the page’s metadata - // will be made absolute correctly. - - let urlToUse = response.url?.absoluteString ?? homePageURL - faviconURL(urlToUse, data, callback) - } - } - - static private func faviconURL(_ url: String, _ webPageData: Data, _ callback: @escaping (String?) -> Void) { - - serialDispatchQueue.async { - - let md5String = (webPageData as NSData).rs_md5HashString() - if let md5String = md5String, let cachedMetadata = metadataCache[md5String] { - let cachedURL = cachedMetadata.faviconLink - DispatchQueue.main.async { - callback(cachedURL) - } - return - } - - let parserData = ParserData(url: url, data: webPageData) - let htmlMetadata = RSHTMLMetadataParser.htmlMetadata(with: parserData) - if let md5String = md5String { - metadataCache[md5String] = htmlMetadata - } - let url = htmlMetadata.faviconLink - DispatchQueue.main.async { - callback(url) - } + HTMLMetadataDownloader.downloadMetadata(for: homePageURL) { (htmlMetadata) in + callback(htmlMetadata?.faviconLink) } } } diff --git a/Evergreen/HTMLMetadata/HTMLMetadataDownloader.swift b/Evergreen/HTMLMetadata/HTMLMetadataDownloader.swift index 24206fff7..26fa2fa5d 100644 --- a/Evergreen/HTMLMetadata/HTMLMetadataDownloader.swift +++ b/Evergreen/HTMLMetadata/HTMLMetadataDownloader.swift @@ -12,6 +12,9 @@ import RSParser struct HTMLMetadataDownloader { + static var metadataCache = [String: RSHTMLMetadata]() + static let serialDispatchQueue = DispatchQueue(label: "HTMLMetadataDownloader") + static func downloadMetadata(for url: String, _ callback: @escaping (RSHTMLMetadata?) -> Void) { guard let actualURL = URL(string: url) else { @@ -25,8 +28,7 @@ struct HTMLMetadataDownloader { let urlToUse = response.url ?? actualURL let parserData = ParserData(url: urlToUse.absoluteString, data: data) - let metadata = RSHTMLMetadataParser.htmlMetadata(with: parserData) - callback(metadata) + parseMetadata(with: parserData, callback) return } @@ -37,4 +39,27 @@ struct HTMLMetadataDownloader { callback(nil) } } + + private static func parseMetadata(with parserData: ParserData, _ callback: @escaping (RSHTMLMetadata?) -> Void) { + + serialDispatchQueue.async { + + let md5String = (parserData.data as NSData).rs_md5HashString() + if let md5String = md5String, let cachedMetadata = metadataCache[md5String] { + DispatchQueue.main.async { + callback(cachedMetadata) + } + return + } + + let htmlMetadata = RSHTMLMetadataParser.htmlMetadata(with: parserData) + if let md5String = md5String { + metadataCache[md5String] = htmlMetadata + } + + DispatchQueue.main.async { + callback(htmlMetadata) + } + } + } }