Use .shared for most of the image downloaders.

This commit is contained in:
Brent Simmons
2024-12-14 15:17:32 -08:00
parent 7c47820455
commit 0e93021f91
7 changed files with 17 additions and 34 deletions

View File

@@ -39,9 +39,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
var userNotificationManager: UserNotificationManager!
var faviconDownloader: FaviconDownloader!
var imageDownloader: ImageDownloader!
var authorAvatarDownloader: AuthorAvatarDownloader!
var webFeedIconDownloader: FeedIconDownloader!
var extensionContainersFile: ExtensionContainersFile!
var extensionFeedAddRequestFile: ExtensionFeedAddRequestFile!
@@ -169,10 +166,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
let imagesFolder = (cacheFolder as NSString).appendingPathComponent("Images")
let imagesFolderURL = URL(fileURLWithPath: imagesFolder)
try! FileManager.default.createDirectory(at: imagesFolderURL, withIntermediateDirectories: true, attributes: nil)
imageDownloader = ImageDownloader(folder: imagesFolder)
authorAvatarDownloader = AuthorAvatarDownloader(imageDownloader: imageDownloader)
webFeedIconDownloader = FeedIconDownloader(imageDownloader: imageDownloader, folder: cacheFolder)
appName = (Bundle.main.infoDictionary!["CFBundleExecutable"]! as! String)
}

View File

@@ -890,7 +890,7 @@ extension TimelineViewController: NSTableViewDelegate {
}
private func avatarForAuthor(_ author: Author) -> IconImage? {
return appDelegate.authorAvatarDownloader.image(for: author)
return AuthorAvatarDownloader.shared.image(for: author)
}
private func makeTimelineCellEmpty(_ cell: TimelineTableCellView) {

View File

@@ -1038,7 +1038,6 @@
841ABA5F20145EC100980E11 /* BuiltinSmartFeedInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuiltinSmartFeedInspectorViewController.swift; sourceTree = "<group>"; };
84216D0222128B9D0049B9B9 /* DetailWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailWebViewController.swift; sourceTree = "<group>"; };
842611891FCB67AA0086A189 /* FeedIconDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedIconDownloader.swift; sourceTree = "<group>"; };
8426119F1FCB72600086A189 /* FeaturedImageDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedImageDownloader.swift; sourceTree = "<group>"; };
842611A11FCB769D0086A189 /* RSHTMLMetadata+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RSHTMLMetadata+Extension.swift"; sourceTree = "<group>"; };
842E45CD1ED8C308000A8B52 /* AppNotifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppNotifications.swift; sourceTree = "<group>"; };
842E45DC1ED8C54B000A8B52 /* Browser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Browser.swift; sourceTree = "<group>"; };
@@ -1826,7 +1825,6 @@
845213221FCA5B10003B6E93 /* ImageDownloader.swift */,
84E850851FCB60CE0072EA88 /* AuthorAvatarDownloader.swift */,
842611891FCB67AA0086A189 /* FeedIconDownloader.swift */,
8426119F1FCB72600086A189 /* FeaturedImageDownloader.swift */,
842611A11FCB769D0086A189 /* RSHTMLMetadata+Extension.swift */,
);
path = Images;

View File

@@ -84,7 +84,7 @@ private extension IconImageCache {
if let iconImage = webFeedIconImageCache[feedID] {
return iconImage
}
if let iconImage = appDelegate.webFeedIconDownloader.icon(for: webFeed) {
if let iconImage = FeedIconDownloader.shared.icon(for: webFeed) {
webFeedIconImageCache[feedID] = iconImage
return iconImage
}
@@ -120,7 +120,7 @@ private extension IconImageCache {
if let iconImage = authorIconImageCache[author] {
return iconImage
}
if let iconImage = appDelegate.authorAvatarDownloader.image(for: author) {
if let iconImage = AuthorAvatarDownloader.shared.image(for: author) {
authorIconImageCache[author] = iconImage
return iconImage
}

View File

@@ -17,13 +17,14 @@ extension Notification.Name {
final class AuthorAvatarDownloader {
private let imageDownloader: ImageDownloader
public static let shared = AuthorAvatarDownloader()
private let imageDownloader = ImageDownloader.shared
private var cache = [String: IconImage]() // avatarURL: RSImage
private var waitingForAvatarURLs = Set<String>()
init(imageDownloader: ImageDownloader) {
init() {
self.imageDownloader = imageDownloader
NotificationCenter.default.addObserver(self, selector: #selector(imageDidBecomeAvailable(_:)), name: .ImageDidBecomeAvailable, object: imageDownloader)
}

View File

@@ -10,6 +10,7 @@ import Foundation
import os.log
import RSCore
import RSWeb
import Core
extension Notification.Name {
@@ -18,20 +19,21 @@ extension Notification.Name {
final class ImageDownloader {
public static let shared = ImageDownloader()
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "ImageDownloader")
private let folder: String
private var diskCache: BinaryDiskCache
private let queue: DispatchQueue
private var imageCache = [String: Data]() // url: image
private var urlsInProgress = Set<String>()
private var badURLs = Set<String>() // That return a 404 or whatever. Just skip them in the future.
init(folder: String) {
init() {
self.folder = folder
self.diskCache = BinaryDiskCache(folder: folder)
self.queue = DispatchQueue(label: "ImageDownloader serial queue - \(folder)")
let folder = AppConfig.cacheSubfolder(named: "Images")
self.diskCache = BinaryDiskCache(folder: folder.path)
self.queue = DispatchQueue(label: "ImageDownloader serial queue - \(folder.path)")
}
@discardableResult

View File

@@ -41,8 +41,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
var userNotificationManager: UserNotificationManager!
var faviconDownloader: FaviconDownloader!
var imageDownloader: ImageDownloader!
var authorAvatarDownloader: AuthorAvatarDownloader!
var webFeedIconDownloader: FeedIconDownloader!
var extensionContainersFile: ExtensionContainersFile!
var extensionFeedAddRequestFile: ExtensionFeedAddRequestFile!
var widgetDataEncoder: WidgetDataEncoder!
@@ -230,24 +228,15 @@ private extension AppDelegate {
let tempDir = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
let faviconsFolderURL = tempDir.appendingPathComponent("Favicons")
let imagesFolderURL = tempDir.appendingPathComponent("Images")
try! FileManager.default.createDirectory(at: faviconsFolderURL, withIntermediateDirectories: true, attributes: nil)
let faviconsFolder = faviconsFolderURL.absoluteString
let faviconsFolderPath = faviconsFolder.suffix(from: faviconsFolder.index(faviconsFolder.startIndex, offsetBy: 7))
faviconDownloader = FaviconDownloader(folder: String(faviconsFolderPath))
let imagesFolder = imagesFolderURL.absoluteString
let imagesFolderPath = imagesFolder.suffix(from: imagesFolder.index(imagesFolder.startIndex, offsetBy: 7))
try! FileManager.default.createDirectory(at: imagesFolderURL, withIntermediateDirectories: true, attributes: nil)
imageDownloader = ImageDownloader(folder: String(imagesFolderPath))
authorAvatarDownloader = AuthorAvatarDownloader(imageDownloader: imageDownloader)
let tempFolder = tempDir.absoluteString
let tempFolderPath = tempFolder.suffix(from: tempFolder.index(tempFolder.startIndex, offsetBy: 7))
webFeedIconDownloader = FeedIconDownloader(imageDownloader: imageDownloader, folder: String(tempFolderPath))
}
private func initializeHomeScreenQuickActions() {
let unreadTitle = NSLocalizedString("First Unread", comment: "First Unread")
let unreadIcon = UIApplicationShortcutIcon(systemImageName: "chevron.down.circle")