Remove save if new process that was throwing us out of sync
This commit is contained in:
parent
616597231e
commit
128fcbae5d
|
@ -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, Error>) -> 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, Error>) -> 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)"
|
||||
}
|
||||
|
|
|
@ -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, Error>) -> 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<CKSubscription, Error>) -> Void) {
|
||||
database?.save(subscription) { [weak self] savedSubscription, error in
|
||||
|
|
Loading…
Reference in New Issue