diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 87ded4d0f..3e24e4daa 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -1257,7 +1257,7 @@ private extension Account { completion?() } - operationQueue.addOperation(operation) + operationQueue.add(operation) } func fetchUnreadCounts(_ feeds: Set, _ completion: VoidCompletionBlock?) { @@ -1272,7 +1272,7 @@ private extension Account { completion?() } - operationQueue.addOperation(operation) + operationQueue.add(operation) } func fetchAllUnreadCounts() { @@ -1297,7 +1297,7 @@ private extension Account { } } - operationQueue.addOperation(operation) + operationQueue.add(operation) } func processUnreadCounts(unreadCountDictionary: UnreadCountDictionary, feeds: Set) { diff --git a/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift b/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift index b17105bb3..4e5600e5c 100644 --- a/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift +++ b/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift @@ -127,7 +127,7 @@ final class FeedlyAccountDelegate: AccountDelegate { currentSyncAllOperation = operation - operationQueue.addOperation(operation) + operationQueue.add(operation) } func sendArticleStatus(for account: Account, completion: @escaping ((Result) -> Void)) { @@ -139,7 +139,7 @@ final class FeedlyAccountDelegate: AccountDelegate { completion(.success(())) } } - operationQueue.addOperation(send) + operationQueue.add(send) } /// Attempts to ensure local articles have the same status as they do remotely. @@ -305,7 +305,7 @@ final class FeedlyAccountDelegate: AccountDelegate { completion(result) } - operationQueue.addOperation(addNewFeed) + operationQueue.add(addNewFeed) } catch { DispatchQueue.main.async { @@ -362,7 +362,7 @@ final class FeedlyAccountDelegate: AccountDelegate { completion(result) } - operationQueue.addOperation(addExistingFeed) + operationQueue.add(addExistingFeed) } catch { DispatchQueue.main.async { @@ -494,13 +494,13 @@ final class FeedlyAccountDelegate: AccountDelegate { credentials = try? account.retrieveCredentials(type: .oauthAccessToken) let refreshAccessToken = FeedlyRefreshAccessTokenOperation(account: account, service: self, oauthClient: oauthAuthorizationClient, log: log) - operationQueue.addOperation(refreshAccessToken) + operationQueue.add(refreshAccessToken) } func accountWillBeDeleted(_ account: Account) { let logout = FeedlyLogoutOperation(account: account, service: caller, log: log) // Dispatch on the shared queue because the lifetime of the account delegate is uncertain. - MainThreadOperationQueue.shared.addOperation(logout) + MainThreadOperationQueue.shared.add(logout) } static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result) -> Void) { diff --git a/Frameworks/Account/Feedly/Operations/FeedlyAddExistingFeedOperation.swift b/Frameworks/Account/Feedly/Operations/FeedlyAddExistingFeedOperation.swift index 3fded3d36..76fdde08b 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlyAddExistingFeedOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlyAddExistingFeedOperation.swift @@ -30,18 +30,18 @@ class FeedlyAddExistingFeedOperation: FeedlyOperation, FeedlyOperationDelegate, let addRequest = FeedlyAddFeedToCollectionOperation(account: account, folder: folder, feedResource: resource, feedName: nil, collectionId: collectionId, service: service) addRequest.delegate = self addRequest.downloadProgress = progress - self.operationQueue.addOperation(addRequest) + self.operationQueue.add(addRequest) let createFeeds = FeedlyCreateFeedsForCollectionFoldersOperation(account: account, feedsAndFoldersProvider: addRequest, log: log) createFeeds.downloadProgress = progress createFeeds.addDependency(addRequest) - self.operationQueue.addOperation(createFeeds) + self.operationQueue.add(createFeeds) let finishOperation = FeedlyCheckpointOperation() finishOperation.checkpointDelegate = self finishOperation.downloadProgress = progress finishOperation.addDependency(createFeeds) - self.operationQueue.addOperation(finishOperation) + self.operationQueue.add(finishOperation) } override func run() { diff --git a/Frameworks/Account/Feedly/Operations/FeedlyAddNewFeedOperation.swift b/Frameworks/Account/Feedly/Operations/FeedlyAddNewFeedOperation.swift index 642b8b37c..e3641511e 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlyAddNewFeedOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlyAddNewFeedOperation.swift @@ -54,7 +54,7 @@ class FeedlyAddNewFeedOperation: FeedlyOperation, FeedlyOperationDelegate, Feedl search.delegate = self search.searchDelegate = self search.downloadProgress = progress - self.operationQueue.addOperation(search) + self.operationQueue.add(search) } override func run() { @@ -81,32 +81,32 @@ class FeedlyAddNewFeedOperation: FeedlyOperation, FeedlyOperationDelegate, Feedl let addRequest = FeedlyAddFeedToCollectionOperation(account: account, folder: folder, feedResource: feedResourceId, feedName: feedName, collectionId: collectionId, service: addToCollectionService) addRequest.delegate = self addRequest.downloadProgress = downloadProgress - operationQueue.addOperation(addRequest) + operationQueue.add(addRequest) let createFeeds = FeedlyCreateFeedsForCollectionFoldersOperation(account: account, feedsAndFoldersProvider: addRequest, log: log) createFeeds.delegate = self createFeeds.addDependency(addRequest) createFeeds.downloadProgress = downloadProgress - operationQueue.addOperation(createFeeds) + operationQueue.add(createFeeds) let syncUnread = FeedlyIngestUnreadArticleIdsOperation(account: account, credentials: credentials, service: syncUnreadIdsService, database: database, newerThan: nil, log: log) syncUnread.addDependency(createFeeds) syncUnread.downloadProgress = downloadProgress syncUnread.delegate = self - operationQueue.addOperation(syncUnread) + operationQueue.add(syncUnread) let syncFeed = FeedlySyncStreamContentsOperation(account: account, resource: feedResourceId, service: getStreamContentsService, isPagingEnabled: false, newerThan: nil, log: log) syncFeed.addDependency(syncUnread) syncFeed.downloadProgress = downloadProgress syncFeed.delegate = self - operationQueue.addOperation(syncFeed) + operationQueue.add(syncFeed) let finishOperation = FeedlyCheckpointOperation() finishOperation.checkpointDelegate = self finishOperation.downloadProgress = downloadProgress finishOperation.addDependency(syncFeed) finishOperation.delegate = self - operationQueue.addOperation(finishOperation) + operationQueue.add(finishOperation) } func feedlyOperation(_ operation: FeedlyOperation, didFailWith error: Error) { diff --git a/Frameworks/Account/Feedly/Operations/FeedlyDownloadArticlesOperation.swift b/Frameworks/Account/Feedly/Operations/FeedlyDownloadArticlesOperation.swift index f5131fab9..550ee34d7 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlyDownloadArticlesOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlyDownloadArticlesOperation.swift @@ -31,7 +31,7 @@ class FeedlyDownloadArticlesOperation: FeedlyOperation { self.log = log super.init() self.finishOperation.checkpointDelegate = self - self.operationQueue.addOperation(self.finishOperation) + self.operationQueue.add(self.finishOperation) } override func run() { @@ -46,14 +46,14 @@ class FeedlyDownloadArticlesOperation: FeedlyOperation { let provider = FeedlyEntryIdentifierProvider(entryIds: Set(articleIds)) let getEntries = FeedlyGetEntriesOperation(account: account, service: getEntriesService, provider: provider, log: log) getEntries.delegate = self - self.operationQueue.addOperation(getEntries) + self.operationQueue.add(getEntries) let organiseByFeed = FeedlyOrganiseParsedItemsByFeedOperation(account: account, parsedItemProvider: getEntries, log: log) organiseByFeed.delegate = self organiseByFeed.addDependency(getEntries) - self.operationQueue.addOperation(organiseByFeed) + self.operationQueue.add(organiseByFeed) let updateAccount = FeedlyUpdateAccountFeedsWithItemsOperation(account: account, organisedItemsProvider: organiseByFeed, @@ -61,7 +61,7 @@ class FeedlyDownloadArticlesOperation: FeedlyOperation { updateAccount.delegate = self updateAccount.addDependency(organiseByFeed) - self.operationQueue.addOperation(updateAccount) + self.operationQueue.add(updateAccount) finishOperation.addDependency(updateAccount) } diff --git a/Frameworks/Account/Feedly/Operations/FeedlySyncAllOperation.swift b/Frameworks/Account/Feedly/Operations/FeedlySyncAllOperation.swift index 3aeae5fc5..b0c87e027 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlySyncAllOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlySyncAllOperation.swift @@ -46,39 +46,39 @@ final class FeedlySyncAllOperation: FeedlyOperation { let sendArticleStatuses = FeedlySendArticleStatusesOperation(database: database, service: markArticlesService, log: log) sendArticleStatuses.delegate = self sendArticleStatuses.downloadProgress = downloadProgress - self.operationQueue.addOperation(sendArticleStatuses) + self.operationQueue.add(sendArticleStatuses) // Get all the Collections the user has. let getCollections = FeedlyGetCollectionsOperation(service: getCollectionsService, log: log) getCollections.delegate = self getCollections.downloadProgress = downloadProgress getCollections.addDependency(sendArticleStatuses) - self.operationQueue.addOperation(getCollections) + self.operationQueue.add(getCollections) // Ensure a folder exists for each Collection, removing Folders without a corresponding Collection. let mirrorCollectionsAsFolders = FeedlyMirrorCollectionsAsFoldersOperation(account: account, collectionsProvider: getCollections, log: log) mirrorCollectionsAsFolders.delegate = self mirrorCollectionsAsFolders.addDependency(getCollections) - self.operationQueue.addOperation(mirrorCollectionsAsFolders) + self.operationQueue.add(mirrorCollectionsAsFolders) // Ensure feeds are created and grouped by their folders. let createFeedsOperation = FeedlyCreateFeedsForCollectionFoldersOperation(account: account, feedsAndFoldersProvider: mirrorCollectionsAsFolders, log: log) createFeedsOperation.delegate = self createFeedsOperation.addDependency(mirrorCollectionsAsFolders) - self.operationQueue.addOperation(createFeedsOperation) + self.operationQueue.add(createFeedsOperation) let getAllArticleIds = FeedlyIngestStreamArticleIdsOperation(account: account, credentials: credentials, service: getStreamIdsService, log: log) getAllArticleIds.delegate = self getAllArticleIds.downloadProgress = downloadProgress getAllArticleIds.addDependency(createFeedsOperation) - self.operationQueue.addOperation(getAllArticleIds) + self.operationQueue.add(getAllArticleIds) // Get each page of unread article ids in the global.all stream for the last 31 days (nil = Feedly API default). let getUnread = FeedlyIngestUnreadArticleIdsOperation(account: account, credentials: credentials, service: getUnreadService, database: database, newerThan: nil, log: log) getUnread.delegate = self getUnread.addDependency(getAllArticleIds) getUnread.downloadProgress = downloadProgress - self.operationQueue.addOperation(getUnread) + self.operationQueue.add(getUnread) // Get each page of the article ids which have been update since the last successful fetch start date. // If the date is nil, this operation provides an empty set (everything is new, nothing is updated). @@ -86,14 +86,14 @@ final class FeedlySyncAllOperation: FeedlyOperation { getUpdated.delegate = self getUpdated.downloadProgress = downloadProgress getUpdated.addDependency(createFeedsOperation) - self.operationQueue.addOperation(getUpdated) + self.operationQueue.add(getUpdated) // Get each page of the article ids for starred articles. let getStarred = FeedlyIngestStarredArticleIdsOperation(account: account, credentials: credentials, service: getStarredService, database: database, newerThan: nil, log: log) getStarred.delegate = self getStarred.downloadProgress = downloadProgress getStarred.addDependency(createFeedsOperation) - self.operationQueue.addOperation(getStarred) + self.operationQueue.add(getStarred) // Now all the possible article ids we need have a status, fetch the article ids for missing articles. let getMissingIds = FeedlyFetchIdsForMissingArticlesOperation(account: account, log: log) @@ -103,7 +103,7 @@ final class FeedlySyncAllOperation: FeedlyOperation { getMissingIds.addDependency(getUnread) getMissingIds.addDependency(getStarred) getMissingIds.addDependency(getUpdated) - self.operationQueue.addOperation(getMissingIds) + self.operationQueue.add(getMissingIds) // Download all the missing and updated articles let downloadMissingArticles = FeedlyDownloadArticlesOperation(account: account, @@ -115,14 +115,14 @@ final class FeedlySyncAllOperation: FeedlyOperation { downloadMissingArticles.downloadProgress = downloadProgress downloadMissingArticles.addDependency(getMissingIds) downloadMissingArticles.addDependency(getUpdated) - self.operationQueue.addOperation(downloadMissingArticles) + self.operationQueue.add(downloadMissingArticles) // Once this operation's dependencies, their dependencies etc finish, we can finish. let finishOperation = FeedlyCheckpointOperation() finishOperation.checkpointDelegate = self finishOperation.downloadProgress = downloadProgress finishOperation.addDependency(downloadMissingArticles) - self.operationQueue.addOperation(finishOperation) + self.operationQueue.add(finishOperation) } convenience init(account: Account, credentials: Credentials, caller: FeedlyAPICaller, database: SyncDatabase, lastSuccessfulFetchStartDate: Date?, downloadProgress: DownloadProgress, log: OSLog) { diff --git a/Frameworks/Account/Feedly/Operations/FeedlySyncStreamContentsOperation.swift b/Frameworks/Account/Feedly/Operations/FeedlySyncStreamContentsOperation.swift index 48e3cee51..7e98eea67 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlySyncStreamContentsOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlySyncStreamContentsOperation.swift @@ -35,7 +35,7 @@ final class FeedlySyncStreamContentsOperation: FeedlyOperation, FeedlyOperationD super.init() - self.operationQueue.addOperation(self.finishOperation) + self.operationQueue.add(self.finishOperation) self.finishOperation.checkpointDelegate = self enqueueOperations(for: nil) } diff --git a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift index bb341bc4f..4e7d9f787 100644 --- a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift +++ b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift @@ -45,6 +45,7 @@ public final class ArticlesDatabase { private let articlesTable: ArticlesTable private let queue: DatabaseQueue + private let operationQueue = MainThreadOperationQueue() public init(databaseFilePath: String, accountID: String) { let queue = DatabaseQueue(databasePath: databaseFilePath) @@ -136,6 +137,15 @@ public final class ArticlesDatabase { } // MARK: - Unread Counts + + public func fetchAllUnreadCounts(_ completion: @escaping UnreadCountDictionaryCompletionBlock) { + let operation = FetchAllUnreadCountsOperation(databaseQueue: queue, cutoffDate: articlesTable.articleCutoffDate) + operation.completionBlock = { operation in + let fetchOperation = operation as! FetchAllUnreadCountsOperation + completion(fetchOperation.result) + } + operationQueue.add(operation) + } public func fetchUnreadCountForToday(for webFeedIDs: Set, completion: @escaping SingleUnreadCountCompletionBlock) { fetchUnreadCount(for: webFeedIDs, since: todayCutoffDate(), completion: completion) @@ -189,6 +199,10 @@ public final class ArticlesDatabase { // MARK: - Operations + public func cancelOperations() { + operationQueue.cancelAllOperations() + } + /// Create an operation that fetches all non-zero unread counts. public func createFetchAllUnreadCountsOperation() -> FetchAllUnreadCountsOperation { return FetchAllUnreadCountsOperation(databaseQueue: queue, cutoffDate: articlesTable.articleCutoffDate) diff --git a/Frameworks/ArticlesDatabase/Operations/FetchAllUnreadCountsOperation.swift b/Frameworks/ArticlesDatabase/Operations/FetchAllUnreadCountsOperation.swift index f02fcf8b6..52c3c4ff2 100644 --- a/Frameworks/ArticlesDatabase/Operations/FetchAllUnreadCountsOperation.swift +++ b/Frameworks/ArticlesDatabase/Operations/FetchAllUnreadCountsOperation.swift @@ -12,13 +12,13 @@ import RSDatabase public final class FetchAllUnreadCountsOperation: MainThreadOperation { - public var unreadCountDictionary: UnreadCountDictionary? + public var result: UnreadCountDictionaryCompletionResult = .failure(.isSuspended) // MainThreadOperation public var isCanceled = false public var id: Int? public weak var operationDelegate: MainThreadOperationDelegate? - public var name: String? + public var name: String? = "FetchAllUnreadCountsOperation" public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock? private let queue: DatabaseQueue @@ -56,7 +56,7 @@ private extension FetchAllUnreadCountsOperation { return } - var d = UnreadCountDictionary() + var unreadCountDictionary = UnreadCountDictionary() while resultSet.next() { if isCanceled { resultSet.close() @@ -65,12 +65,12 @@ private extension FetchAllUnreadCountsOperation { } let unreadCount = resultSet.long(forColumnIndex: 1) if let webFeedID = resultSet.string(forColumnIndex: 0) { - d[webFeedID] = unreadCount + unreadCountDictionary[webFeedID] = unreadCount } } resultSet.close() - unreadCountDictionary = d + result = .success(unreadCountDictionary) informOperationDelegateOfCompletion() } } diff --git a/Frameworks/ArticlesDatabase/Operations/FetchFeedUnreadCountOperation.swift b/Frameworks/ArticlesDatabase/Operations/FetchFeedUnreadCountOperation.swift index 397fbad4c..80b8a7cf0 100644 --- a/Frameworks/ArticlesDatabase/Operations/FetchFeedUnreadCountOperation.swift +++ b/Frameworks/ArticlesDatabase/Operations/FetchFeedUnreadCountOperation.swift @@ -20,7 +20,7 @@ public final class FetchFeedUnreadCountOperation: MainThreadOperation { public var isCanceled = false public var id: Int? public weak var operationDelegate: MainThreadOperationDelegate? - public var name: String? + public var name: String? = "FetchFeedUnreadCountOperation" public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock? private let queue: DatabaseQueue diff --git a/Frameworks/ArticlesDatabase/Operations/FetchUnreadCountsForFeedsOperation.swift b/Frameworks/ArticlesDatabase/Operations/FetchUnreadCountsForFeedsOperation.swift index 38b2c9d22..d3051df68 100644 --- a/Frameworks/ArticlesDatabase/Operations/FetchUnreadCountsForFeedsOperation.swift +++ b/Frameworks/ArticlesDatabase/Operations/FetchUnreadCountsForFeedsOperation.swift @@ -20,7 +20,7 @@ public final class FetchUnreadCountsForFeedsOperation: MainThreadOperation { public var isCanceled = false public var id: Int? public weak var operationDelegate: MainThreadOperationDelegate? - public var name: String? + public var name: String? = "FetchUnreadCountsForFeedsOperation" public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock? private let queue: DatabaseQueue