diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift index 0208c8776..c3db40cb5 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift @@ -415,13 +415,11 @@ enum CloudKitAccountDelegateError: LocalizedError { } self.database.insertStatuses(syncStatuses) { _ in - self.database.selectPendingCount { result in - MainActor.assumeIsolated { - if let count = try? result.get(), count > 100 { - self.sendArticleStatus(for: account, showProgress: false) { _ in } - } - completion(.success(())) + Task { @MainActor in + if let count = try? await self.database.selectPendingCount(), count > 100 { + self.sendArticleStatus(for: account, showProgress: false) { _ in } } + completion(.success(())) } } case .failure(let error): diff --git a/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift index 7861e2153..bbfee35ef 100644 --- a/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift @@ -34,31 +34,23 @@ class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate { func cloudKitDidModify(changed: [CKRecord], deleted: [CloudKitRecordKey], completion: @escaping (Result) -> Void) { - database.selectPendingReadStatusArticleIDs() { result in - switch result { - case .success(let pendingReadStatusArticleIDs): + Task { @MainActor in + do { - Task { @MainActor in + let pendingReadStatusArticleIDs = (try await self.database.selectPendingReadStatusArticleIDs()) ?? Set() + let pendingStarredStatusArticleIDs = (try await self.database.selectPendingStarredStatusArticleIDs()) ?? Set() - do { - - let pendingStarredStatusArticleIDs = (try await self.database.selectPendingStarredStatusArticleIDs()) ?? Set() - self.delete(recordKeys: deleted, pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs) { - Task { @MainActor in - self.update(records: changed, - pendingReadStatusArticleIDs: pendingReadStatusArticleIDs, - pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs, - completion: completion) - } - } - - } catch { - os_log(.error, log: self.log, "Error occurred getting pending starred records: %@", error.localizedDescription) - completion(.failure(CloudKitZoneError.unknown)) + self.delete(recordKeys: deleted, pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs) { + Task { @MainActor in + self.update(records: changed, + pendingReadStatusArticleIDs: pendingReadStatusArticleIDs, + pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs, + completion: completion) } } - case .failure(let error): - os_log(.error, log: self.log, "Error occurred getting pending read status records: %@", error.localizedDescription) + + } catch { + os_log(.error, log: self.log, "Error occurred getting pending status records: %@", error.localizedDescription) completion(.failure(CloudKitZoneError.unknown)) } } diff --git a/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift b/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift index e55041833..c31143cf3 100644 --- a/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift +++ b/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift @@ -16,10 +16,10 @@ import Core import CloudKitExtras class CloudKitSendStatusOperation: MainThreadOperation { - + private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit") private let blockSize = 150 - + // MainThreadOperation public var isCanceled = false public var id: Int? @@ -40,34 +40,30 @@ class CloudKitSendStatusOperation: MainThreadOperation { self.showProgress = showProgress self.database = database } - + @MainActor func run() { os_log(.debug, log: log, "Sending article statuses...") - + if showProgress { - - database.selectPendingCount() { result in - MainActor.assumeIsolated { - switch result { - case .success(let count): - let ticks = count / self.blockSize - self.refreshProgress?.addToNumberOfTasksAndRemaining(ticks) - self.selectForProcessing() - case .failure(let databaseError): - os_log(.error, log: self.log, "Send status count pending error: %@.", databaseError.localizedDescription) - self.operationDelegate?.cancelOperation(self) - } + + Task { @MainActor in + + do { + let count = (try await self.database.selectPendingCount()) ?? 0 + let ticks = count / self.blockSize + self.refreshProgress?.addToNumberOfTasksAndRemaining(ticks) + self.selectForProcessing() + } catch { + os_log(.error, log: self.log, "Send status count pending error: %@.", error.localizedDescription) + self.operationDelegate?.cancelOperation(self) } } } else { - + selectForProcessing() - } - } - } private extension CloudKitSendStatusOperation { diff --git a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift index ffbcdbf05..d913e6eff 100644 --- a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift @@ -563,15 +563,14 @@ final class FeedbinAccountDelegate: AccountDelegate { let syncStatuses = articles.map { article in return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag) } - + self.database.insertStatuses(syncStatuses) { _ in - self.database.selectPendingCount { result in - MainActor.assumeIsolated { - if let count = try? result.get(), count > 100 { - self.sendArticleStatus(for: account) { _ in } - } - completion(.success(())) + + Task { @MainActor in + if let count = try? await self.database.selectPendingCount(), count > 100 { + self.sendArticleStatus(for: account) { _ in } } + completion(.success(())) } } case .failure(let error): @@ -1304,9 +1303,10 @@ private extension FeedbinAccountDelegate { return } - database.selectPendingReadStatusArticleIDs() { result in + Task { @MainActor in + do { - MainActor.assumeIsolated { + let pendingArticleIDs = (try await self.database.selectPendingReadStatusArticleIDs()) ?? Set() @MainActor func process(_ pendingArticleIDs: Set) { @@ -1340,18 +1340,14 @@ private extension FeedbinAccountDelegate { } } } - } - switch result { - case .success(let pendingArticleIDs): - process(pendingArticleIDs) - case .failure(let error): - os_log(.error, log: self.log, "Sync Article Read Status failed: %@.", error.localizedDescription) - } + process(pendingArticleIDs) + + } catch { + os_log(.error, log: self.log, "Sync Article Read Status failed: %@.", error.localizedDescription) } } - } func syncArticleStarredState(account: Account, articleIDs: [Int]?, completion: @escaping (() -> Void)) { diff --git a/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift b/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift index 8e6edee41..9cc3de1cd 100644 --- a/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift +++ b/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift @@ -515,13 +515,12 @@ final class FeedlyAccountDelegate: AccountDelegate { } self.database.insertStatuses(syncStatuses) { _ in - self.database.selectPendingCount { result in - MainActor.assumeIsolated { - if let count = try? result.get(), count > 100 { - self.sendArticleStatus(for: account) { _ in } - } - completion(.success(())) + + Task { @MainActor in + if let count = try? await self.database.selectPendingCount(), count > 100 { + self.sendArticleStatus(for: account) { _ in } } + completion(.success(())) } } case .failure(let error): diff --git a/Account/Sources/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift b/Account/Sources/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift index 2bda79cca..cc8839eda 100644 --- a/Account/Sources/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift +++ b/Account/Sources/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift @@ -324,24 +324,27 @@ extension NewsBlurAccountDelegate { } func syncStoryReadState(account: Account, hashes: [NewsBlurStoryHash]?, completion: @escaping (() -> Void)) { + guard let hashes = hashes else { completion() return } - - database.selectPendingReadStatusArticleIDs() { result in - MainActor.assumeIsolated { + + Task { @MainActor in + do { + let pendingArticleIDs = (try await self.database.selectPendingReadStatusArticleIDs()) ?? Set() + @MainActor func process(_ pendingStoryHashes: Set) { - + let newsBlurUnreadStoryHashes = Set(hashes.map { $0.hash } ) let updatableNewsBlurUnreadStoryHashes = newsBlurUnreadStoryHashes.subtracting(pendingStoryHashes) - + account.fetchUnreadArticleIDs { articleIDsResult in MainActor.assumeIsolated { guard let currentUnreadArticleIDs = try? articleIDsResult.get() else { return } - + let group = DispatchGroup() // Mark articles as unread @@ -350,27 +353,24 @@ extension NewsBlurAccountDelegate { account.markAsUnread(deltaUnreadArticleIDs) { _ in group.leave() } - + // Mark articles as read let deltaReadArticleIDs = currentUnreadArticleIDs.subtracting(updatableNewsBlurUnreadStoryHashes) group.enter() account.markAsRead(deltaReadArticleIDs) { _ in group.leave() } - + group.notify(queue: DispatchQueue.main) { completion() } } } } - - switch result { - case .success(let pendingArticleIDs): - process(pendingArticleIDs) - case .failure(let error): - os_log(.error, log: self.log, "Sync Story Read Status failed: %@.", error.localizedDescription) - } + + process(pendingArticleIDs) + } catch { + os_log(.error, log: self.log, "Sync Story Read Status failed: %@.", error.localizedDescription) } } } diff --git a/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift b/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift index de8ee5221..58788c06c 100644 --- a/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift +++ b/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift @@ -595,13 +595,12 @@ final class NewsBlurAccountDelegate: AccountDelegate { } self.database.insertStatuses(syncStatuses) { _ in - self.database.selectPendingCount { result in - MainActor.assumeIsolated { - if let count = try? result.get(), count > 100 { - self.sendArticleStatus(for: account) { _ in } - } - completion(.success(())) + + Task { @MainActor in + if let count = try? await self.database.selectPendingCount(), count > 100 { + self.sendArticleStatus(for: account) { _ in } } + completion(.success(())) } } case .failure(let error): diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index 9a6732d7e..917b20dfb 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -611,7 +611,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } } - + func markArticles(for account: Account, articles: Set
, statusKey: ArticleStatus.Key, flag: Bool, completion: @escaping (Result) -> Void) { account.update(articles, statusKey: statusKey, flag: flag) { result in switch result { @@ -619,15 +619,14 @@ final class ReaderAPIAccountDelegate: AccountDelegate { let syncStatuses = articles.map { article in return SyncStatus(articleID: article.articleID, key: SyncStatus.Key(statusKey), flag: flag) } - + self.database.insertStatuses(syncStatuses) { _ in - self.database.selectPendingCount { result in - MainActor.assumeIsolated { - if let count = try? result.get(), count > 100 { - self.sendArticleStatus(for: account) { _ in } - } - completion(.success(())) + + Task { @MainActor in + if let count = try? await self.database.selectPendingCount(), count > 100 { + self.sendArticleStatus(for: account) { _ in } } + completion(.success(())) } } case .failure(let error): @@ -635,7 +634,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } } } - + func accountDidInitialize(_ account: Account) { credentials = try? account.retrieveCredentials(type: .readerAPIKey) } @@ -1108,9 +1107,11 @@ private extension ReaderAPIAccountDelegate { return } - database.selectPendingReadStatusArticleIDs() { result in + Task { @MainActor in + do { + + let pendingArticleIDs = (try await self.database.selectPendingReadStatusArticleIDs()) ?? Set() - MainActor.assumeIsolated { @MainActor func process(_ pendingArticleIDs: Set) { let updatableReaderUnreadArticleIDs = Set(articleIDs).subtracting(pendingArticleIDs) @@ -1144,15 +1145,12 @@ private extension ReaderAPIAccountDelegate { } } - switch result { - case .success(let pendingArticleIDs): - process(pendingArticleIDs) - case .failure(let error): - os_log(.error, log: self.log, "Sync Article Read Status failed: %@.", error.localizedDescription) - } + process(pendingArticleIDs) + + } catch { + os_log(.error, log: self.log, "Sync Article Read Status failed: %@.", error.localizedDescription) } } - } func syncArticleStarredState(account: Account, articleIDs: [String]?, completion: @escaping (() -> Void)) { diff --git a/SyncDatabase/Sources/SyncDatabase/SyncDatabase.swift b/SyncDatabase/Sources/SyncDatabase/SyncDatabase.swift index ecdf1dd0c..6f9143c54 100644 --- a/SyncDatabase/Sources/SyncDatabase/SyncDatabase.swift +++ b/SyncDatabase/Sources/SyncDatabase/SyncDatabase.swift @@ -148,37 +148,6 @@ public extension SyncDatabase { } } } - - nonisolated func selectPendingCount(completion: @escaping DatabaseIntCompletionBlock) { - - Task { @MainActor in - do { - if let count = try await self.selectPendingCount() { - completion(.success(count)) - } else { - completion(.success(0)) - } - - } catch { - completion(.failure(DatabaseError.suspended)) - } - } - } - - nonisolated func selectPendingReadStatusArticleIDs(completion: @escaping SyncStatusArticleIDsCompletionBlock) { - - Task { @MainActor in - do { - if let articleIDs = try await self.selectPendingReadStatusArticleIDs() { - completion(.success(articleIDs)) - } else { - completion(.success(Set())) - } - } catch { - completion(.failure(DatabaseError.suspended)) - } - } - } } private extension SyncDatabase {