From 128fcbae5dd407b4e8147a84dad3e13b9ebc632a Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Tue, 28 Apr 2020 11:19:33 -0500 Subject: [PATCH] Remove save if new process that was throwing us out of sync --- .../CloudKit/CloudKitArticlesZone.swift | 52 ++++++------- .../Account/CloudKit/CloudKitZone.swift | 78 ------------------- 2 files changed, 24 insertions(+), 106 deletions(-) diff --git a/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift b/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift index 1e9a013dc..ef9406dbd 100644 --- a/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift +++ b/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift @@ -95,7 +95,7 @@ final class CloudKitArticlesZone: CloudKitZone { records.append(makeArticleRecord(saveArticle)) } - saveIfNew(records, completion: completion) + save(records, completion: completion) } func deleteArticles(_ webFeedExternalID: String, completion: @escaping ((Result) -> Void)) { @@ -110,18 +110,12 @@ final class CloudKitArticlesZone: CloudKitZone { return } - var newRecords = [CKRecord]() var modifyRecords = [CKRecord]() var deleteRecordIDs = [CKRecord.ID]() for statusArticle in statusArticles { switch (statusArticle.status.key, statusArticle.status.flag) { - case (.new, true): - newRecords.append(makeStatusRecord(statusArticle)) - if let article = statusArticle.article { - newRecords.append(makeArticleRecord(article)) - } - case (.new, false): + case (.new, _): modifyRecords.append(makeStatusRecord(statusArticle)) if let article = statusArticle.article { if article.status.read == false || article.status.starred == true { @@ -141,25 +135,12 @@ final class CloudKitArticlesZone: CloudKitZone { } } - saveIfNew(newRecords) { result in - if case .failure(let error) = result, case CloudKitZoneError.userDeletedZone = error { - self.createZoneRecord() { result in - switch result { - case .success: - self.modifyArticles(statusArticles, completion: completion) - case .failure(let error): - completion(.failure(error)) - } - } - } else { - self.modify(recordsToSave: modifyRecords, recordIDsToDelete: deleteRecordIDs) { result in - switch result { - case .success: - completion(.success(())) - case .failure(let error): - completion(.failure(error)) - } - } + self.modify(recordsToSave: modifyRecords, recordIDsToDelete: deleteRecordIDs) { result in + switch result { + case .success: + completion(.success(())) + case .failure(let error): + self.handleModifyArticlesError(error, statusArticles: statusArticles, completion: completion) } } } @@ -167,7 +148,22 @@ final class CloudKitArticlesZone: CloudKitZone { } private extension CloudKitArticlesZone { - + + func handleModifyArticlesError(_ error: Error, statusArticles: [(status: SyncStatus, article: Article?)], completion: @escaping ((Result) -> Void)) { + if case CloudKitZoneError.userDeletedZone = error { + self.createZoneRecord() { result in + switch result { + case .success: + self.modifyArticles(statusArticles, completion: completion) + case .failure(let error): + completion(.failure(error)) + } + } + } else { + completion(.failure(error)) + } + } + func statusID(_ id: String) -> String { return "s|\(id)" } diff --git a/Frameworks/Account/CloudKit/CloudKitZone.swift b/Frameworks/Account/CloudKit/CloudKitZone.swift index dce770775..f42ab61a1 100644 --- a/Frameworks/Account/CloudKit/CloudKitZone.swift +++ b/Frameworks/Account/CloudKit/CloudKitZone.swift @@ -234,84 +234,6 @@ extension CloudKitZone { modify(recordsToSave: records, recordIDsToDelete: [], completion: completion) } - /// Saves or modifies the records as long as they are unchanged relative to the local version - func saveIfNew(_ records: [CKRecord], completion: @escaping (Result) -> Void) { - guard !records.isEmpty else { - completion(.success(())) - return - } - - let op = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: [CKRecord.ID]()) - op.savePolicy = .ifServerRecordUnchanged - op.isAtomic = false - - op.modifyRecordsCompletionBlock = { [weak self] (_, _, error) in - guard let self = self else { - completion(.failure(CloudKitZoneError.unknown)) - return - } - - switch CloudKitZoneResult.resolve(error) { - case .success: - DispatchQueue.main.async { - completion(.success(())) - } - case .zoneNotFound: - self.createZoneRecord() { result in - switch result { - case .success: - self.saveIfNew(records, completion: completion) - case .failure(let error): - DispatchQueue.main.async { - completion(.failure(error)) - } - } - } - case .userDeletedZone: - DispatchQueue.main.async { - completion(.failure(CloudKitZoneError.userDeletedZone)) - } - case .retry(let timeToWait): - os_log(.error, log: self.log, "%@ zone save if new retry in %f seconds.", Self.zoneID.zoneName, timeToWait) - self.retryIfPossible(after: timeToWait) { - self.saveIfNew(records, completion: completion) - } - case .limitExceeded: - - let chunkedRecords = records.chunked(into: 300) - - let group = DispatchGroup() - var errorOccurred = false - - for chunk in chunkedRecords { - group.enter() - self.saveIfNew(chunk) { result in - if case .failure(let error) = result { - os_log(.error, log: self.log, "%@ zone modify records error: %@", Self.zoneID.zoneName, error.localizedDescription) - errorOccurred = true - } - group.leave() - } - } - - group.notify(queue: DispatchQueue.main) { - if errorOccurred { - completion(.failure(CloudKitZoneError.unknown)) - } else { - completion(.success(())) - } - } - - default: - DispatchQueue.main.async { - completion(.failure(CloudKitError(error!))) - } - } - } - - database?.add(op) - } - /// Save the CKSubscription func save(_ subscription: CKSubscription, completion: @escaping (Result) -> Void) { database?.save(subscription) { [weak self] savedSubscription, error in