From 1381b5b24ecdb281d8bb9803b74eff1656fd1665 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Mon, 27 Apr 2020 02:11:20 -0500 Subject: [PATCH] Delete all the articles when a feed is deleted. --- .../CloudKit/CloudKitAccountDelegate.swift | 5 +- .../CloudKit/CloudKitArticlesZone.swift | 11 +--- .../Account/CloudKit/CloudKitZone.swift | 64 +++++++++++++++++++ 3 files changed, 69 insertions(+), 11 deletions(-) diff --git a/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift b/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift index abf34a3c8..56f82193d 100644 --- a/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift @@ -298,7 +298,7 @@ final class CloudKitAccountDelegate: AccountDelegate { } func restoreWebFeed(for account: Account, feed: WebFeed, container: Container, completion: @escaping (Result) -> Void) { - refreshProgress.addToNumberOfTasksAndRemaining(1) + refreshProgress.addToNumberOfTasksAndRemaining(2) accountZone.createWebFeed(url: feed.url, name: feed.name, editedName: feed.editedName, container: container) { result in self.refreshProgress.completeTask() switch result { @@ -310,16 +310,19 @@ final class CloudKitAccountDelegate: AccountDelegate { switch result { case .success(let articles): self.articlesZone.saveNewArticles(articles) { result in + self.refreshProgress.completeTask() if case .failure(let error) = result { os_log(.error, log: self.log, "Restore articles error: %@.", error.localizedDescription) } } case .failure(let error): + self.refreshProgress.clear() completion(.failure(error)) } } case .failure(let error): + self.refreshProgress.clear() self.processAccountError(account, error) completion(.failure(error)) } diff --git a/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift b/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift index 174b028cf..7131efb1c 100644 --- a/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift +++ b/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift @@ -92,16 +92,7 @@ final class CloudKitArticlesZone: CloudKitZone { func deleteArticles(_ webFeedURL: String, completion: @escaping ((Result) -> Void)) { let predicate = NSPredicate(format: "webFeedURL = %@", webFeedURL) let ckQuery = CKQuery(recordType: CloudKitArticle.recordType, predicate: predicate) - - query(ckQuery) { result in - switch result { - case .success(let records): - let recordIDs = records.map { $0.recordID } - self.delete(recordIDs: recordIDs, completion: completion) - case .failure(let error): - completion(.failure(error)) - } - } + delete(ckQuery: ckQuery, completion: completion) } func deleteArticles(_ articles: Set
, completion: @escaping ((Result) -> Void)) { diff --git a/Frameworks/Account/CloudKit/CloudKitZone.swift b/Frameworks/Account/CloudKit/CloudKitZone.swift index 331a52876..3ab088eaa 100644 --- a/Frameworks/Account/CloudKit/CloudKitZone.swift +++ b/Frameworks/Account/CloudKit/CloudKitZone.swift @@ -344,6 +344,70 @@ extension CloudKitZone { } } + /// Delete CKRecords using a CKQuery + func delete(ckQuery: CKQuery, completion: @escaping (Result) -> Void) { + + var records = [CKRecord]() + + let op = CKQueryOperation(query: ckQuery) + op.recordFetchedBlock = { record in + records.append(record) + } + + op.queryCompletionBlock = { [weak self] (cursor, error) in + guard let self = self else { + completion(.failure(CloudKitZoneError.unknown)) + return + } + + + if let cursor = cursor { + self.delete(cursor: cursor, carriedRecords: records, completion: completion) + } else { + guard !records.isEmpty else { + completion(.success(())) + return + } + + let recordIDs = records.map { $0.recordID } + self.modify(recordsToSave: [], recordIDsToDelete: recordIDs, completion: completion) + } + + } + + database?.add(op) + } + + /// Delete CKRecords using a CKQuery + func delete(cursor: CKQueryOperation.Cursor, carriedRecords: [CKRecord], completion: @escaping (Result) -> Void) { + + var records = [CKRecord]() + + let op = CKQueryOperation(cursor: cursor) + op.recordFetchedBlock = { record in + records.append(record) + } + + op.queryCompletionBlock = { [weak self] (cursor, error) in + guard let self = self else { + completion(.failure(CloudKitZoneError.unknown)) + return + } + + records.append(contentsOf: carriedRecords) + + if let cursor = cursor { + self.delete(cursor: cursor, carriedRecords: records, completion: completion) + } else { + let recordIDs = records.map { $0.recordID } + self.modify(recordsToSave: [], recordIDsToDelete: recordIDs, completion: completion) + } + + } + + database?.add(op) + } + /// Delete a CKRecord using its recordID func delete(recordID: CKRecord.ID, completion: @escaping (Result) -> Void) { modify(recordsToSave: [], recordIDsToDelete: [recordID], completion: completion)