mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Create and use IconImageCache. It centralizes and de-dupes logic for getting feed/article images, and it caches the results, which helps performance.
This commit is contained in:
@@ -248,12 +248,11 @@ private extension ActivityManager {
|
||||
attributeSet.title = feed.nameForDisplay
|
||||
attributeSet.keywords = makeKeywords(feed.nameForDisplay)
|
||||
attributeSet.relatedUniqueIdentifier = ActivityManager.identifer(for: feed)
|
||||
if let iconImage = appDelegate.webFeedIconDownloader.icon(for: feed) {
|
||||
attributeSet.thumbnailData = iconImage.image.dataRepresentation()
|
||||
} else if let iconImage = appDelegate.faviconDownloader.faviconAsIcon(for: feed) {
|
||||
|
||||
if let iconImage = IconImageCache.shared.imageForFeed(feed) {
|
||||
attributeSet.thumbnailData = iconImage.image.dataRepresentation()
|
||||
}
|
||||
|
||||
|
||||
selectingActivity!.contentAttributeSet = attributeSet
|
||||
selectingActivity!.needsSave = true
|
||||
|
||||
|
||||
@@ -96,32 +96,7 @@ extension Article {
|
||||
}
|
||||
|
||||
func iconImage() -> IconImage? {
|
||||
if let authors = authors, authors.count == 1, let author = authors.first {
|
||||
if let image = appDelegate.authorAvatarDownloader.image(for: author) {
|
||||
return image
|
||||
}
|
||||
}
|
||||
|
||||
if let authors = webFeed?.authors, authors.count == 1, let author = authors.first {
|
||||
if let image = appDelegate.authorAvatarDownloader.image(for: author) {
|
||||
return image
|
||||
}
|
||||
}
|
||||
|
||||
guard let webFeed = webFeed else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let feedIconImage = appDelegate.webFeedIconDownloader.icon(for: webFeed)
|
||||
if feedIconImage != nil {
|
||||
return feedIconImage
|
||||
}
|
||||
|
||||
if let faviconImage = appDelegate.faviconDownloader.faviconAsIcon(for: webFeed) {
|
||||
return faviconImage
|
||||
}
|
||||
|
||||
return FaviconGenerator.favicon(webFeed)
|
||||
return IconImageCache.shared.imageForArticle(self)
|
||||
}
|
||||
|
||||
func iconImageUrl(webFeed: WebFeed) -> URL? {
|
||||
|
||||
129
Shared/IconImageCache.swift
Normal file
129
Shared/IconImageCache.swift
Normal file
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// IconImageCache.swift
|
||||
// NetNewsWire-iOS
|
||||
//
|
||||
// Created by Brent Simmons on 5/2/21.
|
||||
// Copyright © 2021 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Account
|
||||
import Articles
|
||||
|
||||
class IconImageCache {
|
||||
|
||||
static var shared = IconImageCache()
|
||||
|
||||
private var smartFeedIconImageCache = [FeedIdentifier: IconImage]()
|
||||
private var webFeedIconImageCache = [FeedIdentifier: IconImage]()
|
||||
private var faviconImageCache = [FeedIdentifier: IconImage]()
|
||||
private var smallIconImageCache = [FeedIdentifier: IconImage]()
|
||||
private var authorIconImageCache = [Author: IconImage]()
|
||||
|
||||
func imageFor(_ feedID: FeedIdentifier) -> IconImage? {
|
||||
if let smartFeed = SmartFeedsController.shared.find(by: feedID) {
|
||||
return imageForFeed(smartFeed)
|
||||
}
|
||||
if let feed = AccountManager.shared.existingFeed(with: feedID) {
|
||||
return imageForFeed(feed)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func imageForFeed(_ feed: Feed) -> IconImage? {
|
||||
guard let feedID = feed.feedID else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let smartFeed = feed as? PseudoFeed {
|
||||
return imageForSmartFeed(smartFeed, feedID)
|
||||
}
|
||||
if let webFeed = feed as? WebFeed, let iconImage = imageForWebFeed(webFeed, feedID) {
|
||||
return iconImage
|
||||
}
|
||||
if let smallIconProvider = feed as? SmallIconProvider {
|
||||
return imageForSmallIconProvider(smallIconProvider, feedID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func imageForArticle(_ article: Article) -> IconImage? {
|
||||
if let iconImage = imageForAuthors(article.authors) {
|
||||
return iconImage
|
||||
}
|
||||
guard let feed = article.webFeed else {
|
||||
return nil
|
||||
}
|
||||
return imageForFeed(feed)
|
||||
}
|
||||
|
||||
func emptyCache() {
|
||||
smartFeedIconImageCache = [FeedIdentifier: IconImage]()
|
||||
webFeedIconImageCache = [FeedIdentifier: IconImage]()
|
||||
faviconImageCache = [FeedIdentifier: IconImage]()
|
||||
smallIconImageCache = [FeedIdentifier: IconImage]()
|
||||
authorIconImageCache = [Author: IconImage]()
|
||||
}
|
||||
}
|
||||
|
||||
private extension IconImageCache {
|
||||
|
||||
func imageForSmartFeed(_ smartFeed: PseudoFeed, _ feedID: FeedIdentifier) -> IconImage? {
|
||||
if let iconImage = smartFeedIconImageCache[feedID] {
|
||||
return iconImage
|
||||
}
|
||||
if let iconImage = smartFeed.smallIcon {
|
||||
smartFeedIconImageCache[feedID] = iconImage
|
||||
return iconImage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func imageForWebFeed(_ webFeed: WebFeed, _ feedID: FeedIdentifier) -> IconImage? {
|
||||
if let iconImage = webFeedIconImageCache[feedID] {
|
||||
return iconImage
|
||||
}
|
||||
if let iconImage = appDelegate.webFeedIconDownloader.icon(for: webFeed) {
|
||||
webFeedIconImageCache[feedID] = iconImage
|
||||
return iconImage
|
||||
}
|
||||
if let faviconImage = faviconImageCache[feedID] {
|
||||
return faviconImage
|
||||
}
|
||||
if let faviconImage = appDelegate.faviconDownloader.faviconAsIcon(for: webFeed) {
|
||||
faviconImageCache[feedID] = faviconImage
|
||||
return faviconImage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func imageForSmallIconProvider(_ provider: SmallIconProvider, _ feedID: FeedIdentifier) -> IconImage? {
|
||||
if let iconImage = smallIconImageCache[feedID] {
|
||||
return iconImage
|
||||
}
|
||||
if let iconImage = provider.smallIcon {
|
||||
smallIconImageCache[feedID] = iconImage
|
||||
return iconImage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func imageForAuthors(_ authors: Set<Author>?) -> IconImage? {
|
||||
guard let authors = authors, authors.count == 1, let author = authors.first else {
|
||||
return nil
|
||||
}
|
||||
return imageForAuthor(author)
|
||||
}
|
||||
|
||||
func imageForAuthor(_ author: Author) -> IconImage? {
|
||||
if let iconImage = authorIconImageCache[author] {
|
||||
return iconImage
|
||||
}
|
||||
if let iconImage = appDelegate.authorAvatarDownloader.image(for: author) {
|
||||
authorIconImageCache[author] = iconImage
|
||||
return iconImage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user