NetNewsWire/Frameworks/Account/CloudKit/CloudKitResult.swift

68 lines
1.6 KiB
Swift
Raw Normal View History

2020-03-27 19:59:42 +01:00
//
// CloudKitResult.swift
// Account
//
// Created by Maurice Parker on 3/26/20.
// Copyright © 2020 Ranchero Software, LLC. All rights reserved.
//
import Foundation
import CloudKit
2020-03-29 10:43:20 +02:00
enum CloudKitZoneResult {
2020-03-27 19:59:42 +01:00
case success
case retry(afterSeconds: Double)
2020-03-29 10:43:20 +02:00
case limitExceeded
2020-03-27 19:59:42 +01:00
case changeTokenExpired
2020-03-29 10:43:20 +02:00
case partialFailure(errors: [CKRecord.ID: CKError])
2020-03-27 19:59:42 +01:00
case serverRecordChanged
case noZone
case failure(error: Error)
2020-03-29 10:43:20 +02:00
static func resolve(_ error: Error?) -> CloudKitZoneResult {
2020-03-27 19:59:42 +01:00
guard error != nil else { return .success }
guard let ckError = error as? CKError else {
return .failure(error: error!)
}
switch ckError.code {
case .serviceUnavailable, .requestRateLimited, .zoneBusy:
if let retry = ckError.userInfo[CKErrorRetryAfterKey] as? Double {
return .retry(afterSeconds: retry)
} else {
return .failure(error: error!)
}
case .changeTokenExpired:
return .changeTokenExpired
case .serverRecordChanged:
return .serverRecordChanged
case .partialFailure:
2020-03-29 10:43:20 +02:00
if let partialErrors = ckError.userInfo[CKPartialErrorsByItemIDKey] as? [CKRecord.ID: CKError] {
if anyZoneErrors(partialErrors) {
return .noZone
} else {
return .partialFailure(errors: partialErrors)
}
} else {
return .failure(error: error!)
}
2020-03-27 19:59:42 +01:00
case .limitExceeded:
2020-03-29 10:43:20 +02:00
return .limitExceeded
2020-03-27 19:59:42 +01:00
default:
return .failure(error: error!)
}
}
}
2020-03-29 10:43:20 +02:00
private extension CloudKitZoneResult {
static func anyZoneErrors(_ errors: [CKRecord.ID: CKError]) -> Bool {
return errors.values.contains(where: { $0.code == .zoneNotFound || $0.code == .userDeletedZone } )
}
}