diff --git a/Images/Sources/Images/AuthorAvatarDownloader.swift b/Images/Sources/Images/AuthorAvatarDownloader.swift index db6e8df9e..9feb0f13a 100644 --- a/Images/Sources/Images/AuthorAvatarDownloader.swift +++ b/Images/Sources/Images/AuthorAvatarDownloader.swift @@ -17,13 +17,12 @@ public extension Notification.Name { @MainActor public 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() - public init(imageDownloader: ImageDownloader) { - - self.imageDownloader = imageDownloader + init() { NotificationCenter.default.addObserver(self, selector: #selector(imageDidBecomeAvailable(_:)), name: .ImageDidBecomeAvailable, object: imageDownloader) } diff --git a/Images/Sources/Images/Favicons/FaviconDownloader.swift b/Images/Sources/Images/Favicons/FaviconDownloader.swift index 3274bdec9..a194d6b0e 100644 --- a/Images/Sources/Images/Favicons/FaviconDownloader.swift +++ b/Images/Sources/Images/Favicons/FaviconDownloader.swift @@ -13,6 +13,7 @@ import Account import UniformTypeIdentifiers import Core import ParserObjC +import AppConfig public extension Notification.Name { static let FaviconDidBecomeAvailable = Notification.Name("FaviconDidBecomeAvailableNotification") // userInfo key: FaviconDownloader.UserInfoKey.faviconURL @@ -27,16 +28,18 @@ public protocol FaviconDownloaderDelegate { @MainActor public final class FaviconDownloader { + public static let shared = FaviconDownloader() + private static let saveQueue = CoalescingQueue(name: "Cache Save Queue", interval: 1.0) - private let folder: String + private let folder: URL private let diskCache: BinaryDiskCache private var singleFaviconDownloaderCache = [String: SingleFaviconDownloader]() // faviconURL: SingleFaviconDownloader private var remainingFaviconURLs = [String: ArraySlice]() // homePageURL: array of faviconURLs that haven't been checked yet private var currentHomePageHasOnlyFaviconICO = false private var homePageToFaviconURLCache = [String: String]() //homePageURL: faviconURL - private var homePageToFaviconURLCachePath: String + private var homePageToFaviconURLCachePath: URL private var homePageToFaviconURLCacheDirty = false { didSet { queueSaveHomePageToFaviconURLCacheIfNeeded() @@ -44,7 +47,7 @@ public protocol FaviconDownloaderDelegate { } private var homePageURLsWithNoFaviconURLCache = Set() - private var homePageURLsWithNoFaviconURLCachePath: String + private var homePageURLsWithNoFaviconURLCachePath: URL private var homePageURLsWithNoFaviconURLCacheDirty = false { didSet { queueSaveHomePageURLsWithNoFaviconURLCacheIfNeeded() @@ -60,14 +63,14 @@ public protocol FaviconDownloaderDelegate { static let faviconURL = "faviconURL" } - public init(folder: String) { + public init() { - self.folder = folder - self.diskCache = BinaryDiskCache(folder: folder) + self.folder = AppLocations.faviconsFolder + self.diskCache = BinaryDiskCache(folder: folder.path) self.queue = DispatchQueue(label: "FaviconDownloader serial queue - \(folder)") - self.homePageToFaviconURLCachePath = (folder as NSString).appendingPathComponent("HomePageToFaviconURLCache.plist") - self.homePageURLsWithNoFaviconURLCachePath = (folder as NSString).appendingPathComponent("HomePageURLsWithNoFaviconURLCache.plist") + self.homePageToFaviconURLCachePath = folder.appendingPathComponent("HomePageToFaviconURLCache.plist") + self.homePageURLsWithNoFaviconURLCachePath = folder.appendingPathComponent("HomePageURLsWithNoFaviconURLCache.plist") loadHomePageToFaviconURLCache() loadHomePageURLsWithNoFaviconURLCache() @@ -262,8 +265,7 @@ private extension FaviconDownloader { } func loadHomePageToFaviconURLCache() { - let url = URL(fileURLWithPath: homePageToFaviconURLCachePath) - guard let data = try? Data(contentsOf: url) else { + guard let data = try? Data(contentsOf: homePageToFaviconURLCachePath) else { return } let decoder = PropertyListDecoder() @@ -271,8 +273,7 @@ private extension FaviconDownloader { } func loadHomePageURLsWithNoFaviconURLCache() { - let url = URL(fileURLWithPath: homePageURLsWithNoFaviconURLCachePath) - guard let data = try? Data(contentsOf: url) else { + guard let data = try? Data(contentsOf: homePageURLsWithNoFaviconURLCachePath) else { return } let decoder = PropertyListDecoder() @@ -297,10 +298,9 @@ private extension FaviconDownloader { let encoder = PropertyListEncoder() encoder.outputFormat = .binary - let url = URL(fileURLWithPath: homePageToFaviconURLCachePath) do { let data = try encoder.encode(homePageToFaviconURLCache) - try data.write(to: url) + try data.write(to: homePageToFaviconURLCachePath) } catch { assertionFailure(error.localizedDescription) } @@ -311,10 +311,9 @@ private extension FaviconDownloader { let encoder = PropertyListEncoder() encoder.outputFormat = .binary - let url = URL(fileURLWithPath: homePageURLsWithNoFaviconURLCachePath) do { let data = try encoder.encode(Array(homePageURLsWithNoFaviconURLCache)) - try data.write(to: url) + try data.write(to: homePageURLsWithNoFaviconURLCachePath) } catch { assertionFailure(error.localizedDescription) } diff --git a/Images/Sources/Images/FeedIconDownloader.swift b/Images/Sources/Images/FeedIconDownloader.swift index d677deaa4..2c0ee56c4 100644 --- a/Images/Sources/Images/FeedIconDownloader.swift +++ b/Images/Sources/Images/FeedIconDownloader.swift @@ -28,11 +28,13 @@ public protocol FeedIconDownloaderDelegate: Sendable { @MainActor public final class FeedIconDownloader { + public static let shared = FeedIconDownloader() + public static let feedKey = "url" private static let saveQueue = CoalescingQueue(name: "Cache Save Queue", interval: 1.0) - private let imageDownloader: ImageDownloader + private let imageDownloader = ImageDownloader.shared private var feedURLToIconURLCache = [String: String]() private var feedURLToIconURLCachePath: String @@ -68,8 +70,8 @@ public protocol FeedIconDownloaderDelegate: Sendable { public var delegate: FeedIconDownloaderDelegate? - public init(imageDownloader: ImageDownloader, folder: String) { - self.imageDownloader = imageDownloader + public init(folder: String) { + self.feedURLToIconURLCachePath = (folder as NSString).appendingPathComponent("FeedURLToIconURLCache.plist") self.homePageToIconURLCachePath = (folder as NSString).appendingPathComponent("HomePageToIconURLCache.plist") self.homePagesWithNoIconURLCachePath = (folder as NSString).appendingPathComponent("HomePagesWithNoIconURLCache.plist") diff --git a/Images/Sources/Images/ImageDownloader.swift b/Images/Sources/Images/ImageDownloader.swift index dd68512ff..2159ba9f9 100644 --- a/Images/Sources/Images/ImageDownloader.swift +++ b/Images/Sources/Images/ImageDownloader.swift @@ -11,6 +11,7 @@ import os.log import Web import FoundationExtras import Core +import AppConfig public extension Notification.Name { @@ -19,6 +20,8 @@ public extension Notification.Name { @MainActor public final class ImageDownloader { + public static let shared = ImageDownloader() + public static let imageURLKey = "url" private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "ImageDownloader") @@ -28,7 +31,8 @@ public extension Notification.Name { private var urlsInProgress = Set() private var badURLs = Set() // That return a 404 or whatever. Just skip them in the future. - public init(folder: String) { + init() { + let folder = AppLocations.imagesFolder.path self.diskCache = BinaryDiskCache(folder: folder) }