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