From e31b76d627b2c421e09a5928cb6b8c6da60eb832 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 2 Dec 2017 21:27:25 -0800 Subject: [PATCH] =?UTF-8?q?Delete=20SeekingFavicon,=20which=20wasn?= =?UTF-8?q?=E2=80=99t=20needed=20as=20a=20separate=20object.=20Save=20a=20?= =?UTF-8?q?little=20memory=20this=20way=20too.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Evergreen.xcodeproj/project.pbxproj | 4 -- Evergreen/Favicons/FaviconDownloader.swift | 82 ++++++++++++---------- Evergreen/Favicons/SeekingFavicon.swift | 58 --------------- 3 files changed, 46 insertions(+), 98 deletions(-) delete mode 100644 Evergreen/Favicons/SeekingFavicon.swift diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index 2d0879162..5406b55ff 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -20,7 +20,6 @@ 84513F901FAA63950023A1A9 /* FeedListControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */; }; 845213231FCA5B11003B6E93 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845213221FCA5B10003B6E93 /* ImageDownloader.swift */; }; 845A29091FC74B8E007B49E3 /* SingleFaviconDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */; }; - 845A291B1FC75AA6007B49E3 /* SeekingFavicon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A291A1FC75AA6007B49E3 /* SeekingFavicon.swift */; }; 845A29221FC9251E007B49E3 /* SidebarCellLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A29211FC9251E007B49E3 /* SidebarCellLayout.swift */; }; 845A29241FC9255E007B49E3 /* SidebarCellAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A29231FC9255E007B49E3 /* SidebarCellAppearance.swift */; }; 845EE7B11FC2366500854A1F /* StarredFeedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845EE7B01FC2366500854A1F /* StarredFeedDelegate.swift */; }; @@ -421,7 +420,6 @@ 84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListControlsView.swift; sourceTree = ""; }; 845213221FCA5B10003B6E93 /* ImageDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageDownloader.swift; sourceTree = ""; }; 845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleFaviconDownloader.swift; sourceTree = ""; }; - 845A291A1FC75AA6007B49E3 /* SeekingFavicon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeekingFavicon.swift; sourceTree = ""; }; 845A29211FC9251E007B49E3 /* SidebarCellLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarCellLayout.swift; sourceTree = ""; }; 845A29231FC9255E007B49E3 /* SidebarCellAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarCellAppearance.swift; sourceTree = ""; }; 845B14A51FC2299E0013CF92 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; @@ -637,7 +635,6 @@ children = ( 848F6AE41FC29CFA002D422E /* FaviconDownloader.swift */, 845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */, - 845A291A1FC75AA6007B49E3 /* SeekingFavicon.swift */, 84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */, ); name = Favicons; @@ -1370,7 +1367,6 @@ 84F2D5371FC22FCC00998D64 /* PseudoFeed.swift in Sources */, 845EE7C11FC2488C00854A1F /* SmartFeed.swift in Sources */, 84702AA41FA27AC0006B8943 /* MarkReadOrUnreadCommand.swift in Sources */, - 845A291B1FC75AA6007B49E3 /* SeekingFavicon.swift in Sources */, 849A979F1ED9F130007D329B /* SidebarCell.swift in Sources */, 849A97651ED9EB96007D329B /* SidebarTreeControllerDelegate.swift in Sources */, 849A97671ED9EB96007D329B /* UnreadCountView.swift in Sources */, diff --git a/Evergreen/Favicons/FaviconDownloader.swift b/Evergreen/Favicons/FaviconDownloader.swift index ef4717d72..45e7a558d 100644 --- a/Evergreen/Favicons/FaviconDownloader.swift +++ b/Evergreen/Favicons/FaviconDownloader.swift @@ -17,10 +17,11 @@ extension Notification.Name { final class FaviconDownloader { - private var seekingFaviconCache = [String: SeekingFavicon]() // homePageURL: SeekingFavicon - private var singleFaviconDownloaderCache = [String: SingleFaviconDownloader]() // faviconURL: SingleFaviconDownloader private let folder: String private let diskCache: BinaryDiskCache + private var singleFaviconDownloaderCache = [String: SingleFaviconDownloader]() // faviconURL: SingleFaviconDownloader + private var homePageToFaviconURLCache = [String: String]() //homePageURL: faviconURL + private var homePageURLsWithNoFaviconURL = Set() private let queue: DispatchQueue struct UserInfoKey { @@ -33,7 +34,6 @@ final class FaviconDownloader { self.diskCache = BinaryDiskCache(folder: folder) self.queue = DispatchQueue(label: "FaviconDownloader serial queue - \(folder)") - NotificationCenter.default.addObserver(self, selector: #selector(seekingFaviconDidSeek(_:)), name: .SeekingFaviconSeekDidComplete, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(didLoadFavicon(_:)), name: .DidLoadFavicon, object: nil) } @@ -61,22 +61,30 @@ final class FaviconDownloader { func favicon(withHomePageURL homePageURL: String) -> NSImage? { - guard let seekingFavicon = seekingFavicon(with: normalizedHomePageURL(homePageURL)) else { + let url = normalizedHomePageURL(homePageURL) + if homePageURLsWithNoFaviconURL.contains(url) { return nil } - return favicon(withSeekingFavicon: seekingFavicon) + + if let faviconURL = homePageToFaviconURLCache[url] { + return favicon(with: faviconURL) + } + + FaviconURLFinder.findFaviconURL(url) { (faviconURL) in + if let faviconURL = faviconURL { + self.homePageToFaviconURLCache[url] = faviconURL + let _ = self.favicon(with: faviconURL) + } + else { + self.homePageURLsWithNoFaviconURL.insert(url) + } + } + + return nil } // MARK: - Notifications - @objc func seekingFaviconDidSeek(_ note: Notification) { - - guard let seekingFavicon = note.object as? SeekingFavicon else { - return - } - favicon(withSeekingFavicon: seekingFavicon) - } - @objc func didLoadFavicon(_ note: Notification) { guard let singleFaviconDownloader = note.object as? SingleFaviconDownloader else { @@ -92,7 +100,31 @@ final class FaviconDownloader { private extension FaviconDownloader { - private static let localeForLowercasing = Locale(identifier: "en_US") + static let localeForLowercasing = Locale(identifier: "en_US") + + func findFaviconURL(with homePageURL: String, _ completion: @escaping (String?) -> Void) { + + guard let url = URL(string: homePageURL) else { + completion(nil) + return + } + + FaviconURLFinder.findFaviconURL(homePageURL) { (faviconURL) in + + if let faviconURL = faviconURL { + completion(faviconURL) + return + } + + guard let scheme = url.scheme, let host = url.host else { + completion(nil) + return + } + + let defaultFaviconURL = "\(scheme)://\(host)/favicon.ico".lowercased(with: FaviconDownloader.localeForLowercasing) + completion(defaultFaviconURL) + } + } func normalizedHomePageURL(_ url: String) -> String { @@ -112,15 +144,6 @@ private extension FaviconDownloader { return url + "/" } - @discardableResult - func favicon(withSeekingFavicon seekingFavicon: SeekingFavicon) -> NSImage? { - - guard let faviconURL = seekingFavicon.faviconURL else { - return nil - } - return favicon(with: faviconURL) - } - func faviconDownloader(withURL faviconURL: String) -> SingleFaviconDownloader { if let downloader = singleFaviconDownloaderCache[faviconURL] { @@ -133,19 +156,6 @@ private extension FaviconDownloader { return downloader } - func seekingFavicon(with homePageURL: String) -> SeekingFavicon? { - - if let seekingFavicon = seekingFaviconCache[homePageURL] { - return seekingFavicon - } - - guard let seekingFavicon = SeekingFavicon(homePageURL: homePageURL) else { - return nil - } - seekingFaviconCache[homePageURL] = seekingFavicon - return seekingFavicon - } - func postFaviconDidBecomeAvailableNotification(_ faviconURL: String) { let userInfo: [AnyHashable: Any] = [UserInfoKey.faviconURL: faviconURL] diff --git a/Evergreen/Favicons/SeekingFavicon.swift b/Evergreen/Favicons/SeekingFavicon.swift deleted file mode 100644 index 00276c9b7..000000000 --- a/Evergreen/Favicons/SeekingFavicon.swift +++ /dev/null @@ -1,58 +0,0 @@ -// -// SeekingFavicon.swift -// Evergreen -// -// Created by Brent Simmons on 11/23/17. -// Copyright © 2017 Ranchero Software. All rights reserved. -// - -import Foundation - -extension Notification.Name { - - static let SeekingFaviconSeekDidComplete = Notification.Name("SeekingFaviconSeekDidCompleteNotification") -} - -final class SeekingFavicon { - - // At first, when looking for a favicon, we only know the homePageURL. - // The faviconURL may be specified by metadata in the home page, - // or it might be at /favicon.ico, - // or it might not exist (or be unfindable, which is the same thing). - - var didSeek = false - var faviconURL: String? { - return didSeek ? (foundFaviconURL ?? defaultFaviconURL) : nil - } - - private let homePageURL: String - private var foundFaviconURL: String? - private let defaultFaviconURL: String // /favicon.ico - private static let localeForLowercasing = Locale(identifier: "en_US") - - init?(homePageURL: String) { - - guard let url = URL(string: homePageURL), let scheme = url.scheme, let host = url.host else { - return nil - } - - self.homePageURL = homePageURL - self.defaultFaviconURL = "\(scheme)://\(host)/favicon.ico".lowercased(with: SeekingFavicon.localeForLowercasing) - - findFaviconURL() - } -} - -private extension SeekingFavicon { - - func findFaviconURL() { - - FaviconURLFinder.findFaviconURL(homePageURL) { (faviconURL) in - - self.foundFaviconURL = faviconURL - self.didSeek = true - - NotificationCenter.default.post(name: .SeekingFaviconSeekDidComplete, object: self) - } - } -}