Delete all the articles when a feed is deleted.

This commit is contained in:
Maurice Parker 2020-04-27 02:11:20 -05:00
parent 85fe4abc78
commit 1381b5b24e
3 changed files with 69 additions and 11 deletions

View File

@ -298,7 +298,7 @@ final class CloudKitAccountDelegate: AccountDelegate {
} }
func restoreWebFeed(for account: Account, feed: WebFeed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) { func restoreWebFeed(for account: Account, feed: WebFeed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
refreshProgress.addToNumberOfTasksAndRemaining(1) refreshProgress.addToNumberOfTasksAndRemaining(2)
accountZone.createWebFeed(url: feed.url, name: feed.name, editedName: feed.editedName, container: container) { result in accountZone.createWebFeed(url: feed.url, name: feed.name, editedName: feed.editedName, container: container) { result in
self.refreshProgress.completeTask() self.refreshProgress.completeTask()
switch result { switch result {
@ -310,16 +310,19 @@ final class CloudKitAccountDelegate: AccountDelegate {
switch result { switch result {
case .success(let articles): case .success(let articles):
self.articlesZone.saveNewArticles(articles) { result in self.articlesZone.saveNewArticles(articles) { result in
self.refreshProgress.completeTask()
if case .failure(let error) = result { if case .failure(let error) = result {
os_log(.error, log: self.log, "Restore articles error: %@.", error.localizedDescription) os_log(.error, log: self.log, "Restore articles error: %@.", error.localizedDescription)
} }
} }
case .failure(let error): case .failure(let error):
self.refreshProgress.clear()
completion(.failure(error)) completion(.failure(error))
} }
} }
case .failure(let error): case .failure(let error):
self.refreshProgress.clear()
self.processAccountError(account, error) self.processAccountError(account, error)
completion(.failure(error)) completion(.failure(error))
} }

View File

@ -92,16 +92,7 @@ final class CloudKitArticlesZone: CloudKitZone {
func deleteArticles(_ webFeedURL: String, completion: @escaping ((Result<Void, Error>) -> Void)) { func deleteArticles(_ webFeedURL: String, completion: @escaping ((Result<Void, Error>) -> Void)) {
let predicate = NSPredicate(format: "webFeedURL = %@", webFeedURL) let predicate = NSPredicate(format: "webFeedURL = %@", webFeedURL)
let ckQuery = CKQuery(recordType: CloudKitArticle.recordType, predicate: predicate) let ckQuery = CKQuery(recordType: CloudKitArticle.recordType, predicate: predicate)
delete(ckQuery: ckQuery, completion: completion)
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))
}
}
} }
func deleteArticles(_ articles: Set<Article>, completion: @escaping ((Result<Void, Error>) -> Void)) { func deleteArticles(_ articles: Set<Article>, completion: @escaping ((Result<Void, Error>) -> Void)) {

View File

@ -344,6 +344,70 @@ extension CloudKitZone {
} }
} }
/// Delete CKRecords using a CKQuery
func delete(ckQuery: CKQuery, completion: @escaping (Result<Void, Error>) -> 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, Error>) -> 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 /// Delete a CKRecord using its recordID
func delete(recordID: CKRecord.ID, completion: @escaping (Result<Void, Error>) -> Void) { func delete(recordID: CKRecord.ID, completion: @escaping (Result<Void, Error>) -> Void) {
modify(recordsToSave: [], recordIDsToDelete: [recordID], completion: completion) modify(recordsToSave: [], recordIDsToDelete: [recordID], completion: completion)