Convert several methods to async await.

This commit is contained in:
Brent Simmons 2024-04-10 19:03:41 -07:00
parent 0a626b1904
commit bf4b751c76
3 changed files with 32 additions and 32 deletions

View File

@ -30,14 +30,13 @@ struct FaviconURLFinder {
return
}
// If the favicon has an explicit type, check that for an ignored type; otherwise, check the file extension.
HTMLMetadataDownloader.downloadMetadata(for: homePageURL) { htmlMetadata in
let faviconURLs = htmlMetadata?.favicons.compactMap { favicon -> String? in
Task { @MainActor in
guard shouldAllowFavicon(favicon) else {
return nil
}
return favicon.urlString
// If the favicon has an explicit type, check that for an ignored type; otherwise, check the file extension.
let htmlMetadata = try? await HTMLMetadataDownloader.downloadMetadata(for: homePageURL)
let faviconURLs = htmlMetadata?.favicons.compactMap { favicon -> String? in
shouldAllowFavicon(favicon) ? favicon.urlString : nil
}
completion(faviconURLs)

View File

@ -10,34 +10,35 @@ import Foundation
import Web
import Parser
extension RSHTMLMetadata: @unchecked Sendable {}
struct HTMLMetadataDownloader {
static let serialDispatchQueue = DispatchQueue(label: "HTMLMetadataDownloader")
@MainActor static func downloadMetadata(for url: String) async -> RSHTMLMetadata? {
@MainActor static func downloadMetadata(for url: String, _ completion: @escaping @Sendable (RSHTMLMetadata?) -> Void) {
guard let actualURL = URL(unicodeString: url) else {
completion(nil)
return
return nil
}
downloadUsingCache(actualURL) { (data, response, error) in
if let data = data, !data.isEmpty, let response = response, response.statusIsOK, error == nil {
let urlToUse = response.url ?? actualURL
let parserData = ParserData(url: urlToUse.absoluteString, data: data)
parseMetadata(with: parserData, completion)
return
}
let downloadData = try? await downloadUsingCache(actualURL)
let data = downloadData?.data
let response = downloadData?.response
completion(nil)
if let data, !data.isEmpty, let response, response.statusIsOK {
let urlToUse = response.url ?? actualURL
let parserData = ParserData(url: urlToUse.absoluteString, data: data)
return await parseMetadata(with: parserData)
}
return nil
}
private static func parseMetadata(with parserData: ParserData, _ completion: @escaping @Sendable (RSHTMLMetadata?) -> Void) {
serialDispatchQueue.async {
let htmlMetadata = RSHTMLMetadataParser.htmlMetadata(with: parserData)
DispatchQueue.main.async {
completion(htmlMetadata)
}
@MainActor private static func parseMetadata(with parserData: ParserData) async -> RSHTMLMetadata? {
let task = Task.detached { () -> RSHTMLMetadata? in
RSHTMLMetadataParser.htmlMetadata(with: parserData)
}
return await task.value
}
}

View File

@ -214,15 +214,15 @@ private extension FeedIconDownloader {
}
urlsInProgress.insert(homePageURL)
HTMLMetadataDownloader.downloadMetadata(for: homePageURL) { (metadata) in
Task { @MainActor in
MainActor.assumeIsolated {
self.urlsInProgress.remove(homePageURL)
guard let metadata = metadata else {
return
}
self.pullIconURL(from: metadata, homePageURL: homePageURL, feed: feed)
let metadata = try? await HTMLMetadataDownloader.downloadMetadata(for: homePageURL)
self.urlsInProgress.remove(homePageURL)
guard let metadata else {
return
}
self.pullIconURL(from: metadata, homePageURL: homePageURL, feed: feed)
}
}