From fb423ad495364dd6cb55312d37a2442051fdea4a Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 21 Apr 2024 12:44:15 -0700 Subject: [PATCH] Move CloudKitSendStatusOperation to CloudKitSync module. --- .../CloudKitAccountDelegate.swift | 29 ++++++++++++++-- .../CloudKitReceiveStatusOperation.swift | 2 +- .../CloudKitSendStatusOperation.swift | 34 +++++++++++-------- 3 files changed, 47 insertions(+), 18 deletions(-) rename {Account/Sources/Account/CloudKit => CloudKitSync/Sources/CloudKitSync}/CloudKitSendStatusOperation.swift (81%) diff --git a/Account/Sources/Account/AccountDelegates/CloudKitAccountDelegate.swift b/Account/Sources/Account/AccountDelegates/CloudKitAccountDelegate.swift index 84ea88ecd..95c513f8d 100644 --- a/Account/Sources/Account/AccountDelegates/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/AccountDelegates/CloudKitAccountDelegate.swift @@ -691,11 +691,11 @@ private extension CloudKitAccountDelegate { } private func sendArticleStatus(for account: Account, showProgress: Bool, completion: @escaping ((Result) -> Void)) { - let op = CloudKitSendStatusOperation(account: account, - articlesZone: articlesZone, + let op = CloudKitSendStatusOperation(articlesZone: articlesZone, refreshProgress: refreshProgress, showProgress: showProgress, - database: database) + database: database, + delegate: self) op.completionBlock = { mainThreadOperaion in Task { @MainActor in if mainThreadOperaion.isCanceled { @@ -762,3 +762,26 @@ extension CloudKitAccountDelegate: CloudKitFeedInfoDelegate { article.feed?.url } } + +extension CloudKitAccountDelegate: CloudKitSendStatusOperationDelegate { + + @MainActor func cloudKitSendStatusOperation(_ : CloudKitSendStatusOperation, articlesFor articleIDs: Set) async throws -> Set
{ + + guard let account else { return Set
() } + + return try await account.articles(articleIDs: articleIDs) + } + + @MainActor func cloudKitSendStatusOperation(_ : CloudKitSendStatusOperation, userDidDeleteZone: Error) { + + // Delete feeds and folders + + guard let account else { return } + + account.removeFeeds(account.topLevelFeeds) + + for folder in account.folders ?? Set() { + account.removeFolder(folder: folder) + } + } +} diff --git a/CloudKitSync/Sources/CloudKitSync/CloudKitReceiveStatusOperation.swift b/CloudKitSync/Sources/CloudKitSync/CloudKitReceiveStatusOperation.swift index 0c484aba1..17ce39318 100644 --- a/CloudKitSync/Sources/CloudKitSync/CloudKitReceiveStatusOperation.swift +++ b/CloudKitSync/Sources/CloudKitSync/CloudKitReceiveStatusOperation.swift @@ -10,7 +10,7 @@ import Foundation import os.log import Core -public final class CloudKitReceiveStatusOperation: MainThreadOperation { +@MainActor public final class CloudKitReceiveStatusOperation: MainThreadOperation { private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit") diff --git a/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift b/CloudKitSync/Sources/CloudKitSync/CloudKitSendStatusOperation.swift similarity index 81% rename from Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift rename to CloudKitSync/Sources/CloudKitSync/CloudKitSendStatusOperation.swift index 28c684eb6..a680055f8 100644 --- a/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift +++ b/CloudKitSync/Sources/CloudKitSync/CloudKitSendStatusOperation.swift @@ -14,9 +14,14 @@ import SyncDatabase import Database import Core import CloudKitExtras -import CloudKitSync -class CloudKitSendStatusOperation: MainThreadOperation { +public protocol CloudKitSendStatusOperationDelegate: AnyObject { + + @MainActor func cloudKitSendStatusOperation(_ : CloudKitSendStatusOperation, articlesFor articleIDs: Set) async throws -> Set
+ @MainActor func cloudKitSendStatusOperation(_ : CloudKitSendStatusOperation, userDidDeleteZone: Error) +} + +@MainActor public final class CloudKitSendStatusOperation: MainThreadOperation { private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit") private let blockSize = 150 @@ -28,21 +33,23 @@ class CloudKitSendStatusOperation: MainThreadOperation { public var name: String? = "CloudKitSendStatusOperation" public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock? - private weak var account: Account? private weak var articlesZone: CloudKitArticlesZone? private weak var refreshProgress: DownloadProgress? private var showProgress: Bool private var database: SyncDatabase - init(account: Account, articlesZone: CloudKitArticlesZone, refreshProgress: DownloadProgress, showProgress: Bool, database: SyncDatabase) { - self.account = account + private weak var delegate: CloudKitSendStatusOperationDelegate? + + public init(articlesZone: CloudKitArticlesZone, refreshProgress: DownloadProgress, showProgress: Bool, database: SyncDatabase, delegate: CloudKitSendStatusOperationDelegate) { + self.articlesZone = articlesZone self.refreshProgress = refreshProgress self.showProgress = showProgress self.database = database + self.delegate = delegate } - @MainActor func run() { + @MainActor public func run() { os_log(.debug, log: log, "Sending article statuses...") if showProgress { @@ -102,7 +109,8 @@ private extension CloudKitSendStatusOperation { } @MainActor func processStatuses(_ syncStatuses: [SyncStatus], completion: @escaping (Bool) -> Void) { - guard let account = account, let articlesZone = articlesZone else { + + guard let delegate, let articlesZone else { completion(true) return } @@ -112,7 +120,7 @@ private extension CloudKitSendStatusOperation { Task { @MainActor in do { - let articles = try await account.articles(articleIDs: Set(articleIDs)) + let articles = try await delegate.cloudKitSendStatusOperation(self, articlesFor: Set(articleIDs)) let syncStatusesDict = Dictionary(grouping: syncStatuses, by: { $0.articleID }) let articlesDict = articles.reduce(into: [String: Article]()) { result, article in @@ -148,7 +156,7 @@ private extension CloudKitSendStatusOperation { done(false) case .failure(let error): try? await self.database.resetSelectedForProcessing(syncStatuses.map({ $0.articleID })) - self.processAccountError(account, error) + self.processAccountError(error) os_log(.error, log: self.log, "Send article status modify articles error: %@.", error.localizedDescription) completion(true) } @@ -162,12 +170,10 @@ private extension CloudKitSendStatusOperation { } } - @MainActor func processAccountError(_ account: Account, _ error: Error) { + @MainActor func processAccountError(_ error: Error) { + if case CloudKitZoneError.userDeletedZone = error { - account.removeFeeds(account.topLevelFeeds) - for folder in account.folders ?? Set() { - account.removeFolder(folder: folder) - } + delegate?.cloudKitSendStatusOperation(self, userDidDeleteZone: error) } } }