From 391408f00c4f6b86808143061d0da4c9899898c6 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 25 May 2024 22:47:19 -0700 Subject: [PATCH] Make DownloadSession use String identifier instead of AnyObject. --- .../LocalAccount/LocalAccountRefresher.swift | 186 ------------------ 1 file changed, 186 deletions(-) delete mode 100644 Account/Sources/Account/LocalAccount/LocalAccountRefresher.swift diff --git a/Account/Sources/Account/LocalAccount/LocalAccountRefresher.swift b/Account/Sources/Account/LocalAccount/LocalAccountRefresher.swift deleted file mode 100644 index 9063aa01f..000000000 --- a/Account/Sources/Account/LocalAccount/LocalAccountRefresher.swift +++ /dev/null @@ -1,186 +0,0 @@ -// -// LocalAccountRefresher.swift -// NetNewsWire -// -// Created by Brent Simmons on 9/6/16. -// Copyright © 2016 Ranchero Software, LLC. All rights reserved. -// - -import Foundation -import Parser -import ParserObjC -import Web -import Articles -import ArticlesDatabase -import FoundationExtras - -protocol LocalAccountRefresherDelegate { - @MainActor func localAccountRefresher(_ refresher: LocalAccountRefresher, requestCompletedFor: Feed) - @MainActor func localAccountRefresher(_ refresher: LocalAccountRefresher, articleChanges: ArticleChanges, completion: @escaping () -> Void) -} - -@MainActor final class LocalAccountRefresher { - - private var completion: (() -> Void)? = nil - private var isSuspended = false - var delegate: LocalAccountRefresherDelegate? - - private lazy var downloadSession: DownloadSession = { - return DownloadSession(delegate: self) - }() - - private func refreshFeeds(_ feeds: Set, completion: (() -> Void)? = nil) { - guard !feeds.isEmpty else { - completion?() - return - } - self.completion = completion - downloadSession.downloadObjects(feeds as NSSet) - } - - public func refreshFeeds(_ feeds: Set) async { - - await withCheckedContinuation { continuation in - self.refreshFeeds(feeds) { - continuation.resume() - } - } - } - - public func suspend() { - downloadSession.cancelAll() - isSuspended = true - } - - public func resume() { - isSuspended = false - } - -} - -// MARK: - DownloadSessionDelegate - -extension LocalAccountRefresher: DownloadSessionDelegate { - - @MainActor func downloadSession(_ downloadSession: DownloadSession, requestForRepresentedObject representedObject: AnyObject) -> URLRequest? { - guard let feed = representedObject as? Feed else { - return nil - } - guard let url = URL(string: feed.url) else { - return nil - } - - var request = URLRequest(url: url) - if let conditionalGetInfo = feed.conditionalGetInfo { - conditionalGetInfo.addRequestHeadersToURLRequest(&request) - } - - return request - } - - @MainActor func downloadSession(_ downloadSession: DownloadSession, downloadDidCompleteForRepresentedObject representedObject: AnyObject, response: URLResponse?, data: Data, error: NSError?, completion: @escaping () -> Void) { - let feed = representedObject as! Feed - - guard !data.isEmpty, !isSuspended else { - completion() - delegate?.localAccountRefresher(self, requestCompletedFor: feed) - return - } - - if let error = error { - print("Error downloading \(feed.url) - \(error)") - completion() - delegate?.localAccountRefresher(self, requestCompletedFor: feed) - return - } - - let dataHash = data.md5String - if dataHash == feed.contentHash { - completion() - delegate?.localAccountRefresher(self, requestCompletedFor: feed) - return - } - - let parserData = ParserData(url: feed.url, data: data) - Task { @MainActor in - - do { - let parsedFeed = try await FeedParser.parse(parserData) - - guard let account = feed.account, let parsedFeed else { - completion() - self.delegate?.localAccountRefresher(self, requestCompletedFor: feed) - return - } - - - let articleChanges = try await account.update(feed: feed, with: parsedFeed) - - if let httpResponse = response as? HTTPURLResponse { - feed.conditionalGetInfo = HTTPConditionalGetInfo(urlResponse: httpResponse) - } - feed.contentHash = dataHash - - self.delegate?.localAccountRefresher(self, requestCompletedFor: feed) - self.delegate?.localAccountRefresher(self, articleChanges: articleChanges) { - completion() - } - - } catch { - completion() - self.delegate?.localAccountRefresher(self, requestCompletedFor: feed) - } - } - } - - - func downloadSession(_ downloadSession: DownloadSession, shouldContinueAfterReceivingData data: Data, representedObject: AnyObject) -> Bool { - let feed = representedObject as! Feed - guard !isSuspended else { - delegate?.localAccountRefresher(self, requestCompletedFor: feed) - return false - } - - if data.isEmpty { - return true - } - - if data.isDefinitelyNotFeed() { - delegate?.localAccountRefresher(self, requestCompletedFor: feed) - return false - } - - return true - } - - func downloadSession(_ downloadSession: DownloadSession, didReceiveUnexpectedResponse response: URLResponse, representedObject: AnyObject) { - let feed = representedObject as! Feed - delegate?.localAccountRefresher(self, requestCompletedFor: feed) - } - - func downloadSession(_ downloadSession: DownloadSession, didReceiveNotModifiedResponse: URLResponse, representedObject: AnyObject) { - let feed = representedObject as! Feed - delegate?.localAccountRefresher(self, requestCompletedFor: feed) - } - - func downloadSession(_ downloadSession: DownloadSession, didDiscardDuplicateRepresentedObject representedObject: AnyObject) { - let feed = representedObject as! Feed - delegate?.localAccountRefresher(self, requestCompletedFor: feed) - } - - func downloadSessionDidCompleteDownloadObjects(_ downloadSession: DownloadSession) { - completion?() - completion = nil - } - -} - -// MARK: - Utility - -private extension Data { - - func isDefinitelyNotFeed() -> Bool { - // We only detect a few image types for now. This should get fleshed-out at some later date. - return self.isImage - } -}