Cache parsed metadata when finding a home page’s favicon URL. Also: do the parsing in the background, for performance reasons.

This commit is contained in:
Brent Simmons 2017-12-13 19:46:03 -08:00
parent b3ecf9cdba
commit db1db7b701
1 changed files with 27 additions and 6 deletions

View File

@ -9,11 +9,15 @@
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 {
@ -36,16 +40,33 @@ struct FaviconURLFinder {
// will be made absolute correctly.
let urlToUse = response.url?.absoluteString ?? homePageURL
let link = faviconURL(urlToUse, data)
callback(link)
faviconURL(urlToUse, data, callback)
}
}
static private func faviconURL(_ url: String, _ webPageData: Data) -> String? {
static private func faviconURL(_ url: String, _ webPageData: Data, _ callback: @escaping (String?) -> Void) {
let parserData = ParserData(url: url, data: webPageData)
let htmlMetadata = RSHTMLMetadataParser.htmlMetadata(with: parserData)
return htmlMetadata.faviconLink
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)
}
}
}
}