Enhance remove folder to also remove webfeeds and articles from the cloud

This commit is contained in:
Maurice Parker 2020-05-10 16:59:23 -05:00
parent 8434e7fa1f
commit d22aea7cf5
2 changed files with 68 additions and 6 deletions

View File

@ -27,7 +27,6 @@ enum CloudKitAccountDelegateError: LocalizedError {
}
}
final class CloudKitAccountDelegate: AccountDelegate {
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
@ -320,18 +319,55 @@ final class CloudKitAccountDelegate: AccountDelegate {
}
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
refreshProgress.addToNumberOfTasksAndRemaining(1)
accountZone.removeFolder(folder) { result in
refreshProgress.addToNumberOfTasksAndRemaining(2)
accountZone.findWebFeedExternalIDs(for: folder) { result in
self.refreshProgress.completeTask()
switch result {
case .success:
account.removeFolder(folder)
completion(.success(()))
case .success(let webFeedExternalIDs):
let webFeeds = webFeedExternalIDs.compactMap { account.existingWebFeed(withExternalID: $0) }
let group = DispatchGroup()
var errorOccurred = false
for webFeed in webFeeds {
group.enter()
self.removeWebFeed(for: account, with: webFeed, from: folder) { result in
group.leave()
if case .failure(let error) = result {
os_log(.error, log: self.log, "Remove folder, remove webfeed error: %@.", error.localizedDescription)
errorOccurred = true
}
}
}
group.notify(queue: DispatchQueue.global(qos: .background)) {
guard !errorOccurred else {
self.refreshProgress.completeTask()
completion(.failure(CloudKitAccountDelegateError.unknown))
return
}
self.accountZone.removeFolder(folder) { result in
self.refreshProgress.completeTask()
switch result {
case .success:
account.removeFolder(folder)
completion(.success(()))
case .failure(let error):
completion(.failure(error))
}
}
}
case .failure(let error):
self.refreshProgress.completeTask()
self.refreshProgress.completeTask()
self.processAccountError(account, error)
completion(.failure(error))
}
}
}
func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {

View File

@ -12,6 +12,12 @@ import RSWeb
import RSParser
import CloudKit
enum CloudKitAccountZoneError: LocalizedError {
case unknown
var errorDescription: String? {
return NSLocalizedString("An unexpected CloudKit error occurred.", comment: "An unexpected CloudKit error occurred.")
}
}
final class CloudKitAccountZone: CloudKitZone {
static var zoneID: CKRecordZone.ID {
@ -221,6 +227,26 @@ final class CloudKitAccountZone: CloudKitZone {
}
}
func findWebFeedExternalIDs(for folder: Folder, completion: @escaping (Result<[String], Error>) -> Void) {
guard let folderExternalID = folder.externalID else {
completion(.failure(CloudKitAccountZoneError.unknown))
return
}
let predicate = NSPredicate(format: "containerExternalIDs CONTAINS %@", folderExternalID)
let ckQuery = CKQuery(recordType: CloudKitWebFeed.recordType, predicate: predicate)
query(ckQuery) { result in
switch result {
case .success(let records):
let webFeedExternalIds = records.map { $0.externalID }
completion(.success(webFeedExternalIds))
case .failure(let error):
completion(.failure(error))
}
}
}
func findOrCreateAccount(completion: @escaping (Result<String, Error>) -> Void) {
let predicate = NSPredicate(format: "isAccount = \"1\"")
let ckQuery = CKQuery(recordType: CloudKitContainer.recordType, predicate: predicate)