|
|
@ -202,63 +202,61 @@ import PromiseKit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class func saveRecordToCloud(record: CKRecord) -> Promise<String> {
|
|
|
|
public class func saveRecordToCloud(record: CKRecord) -> Promise<String> {
|
|
|
|
let (promise, resolver) = Promise<String>.pending()
|
|
|
|
return saveRecordToCloud(record: record,
|
|
|
|
saveRecordToCloud(record: record,
|
|
|
|
remainingRetries: maxRetries)
|
|
|
|
remainingRetries: maxRetries,
|
|
|
|
|
|
|
|
success: { (recordName) in
|
|
|
|
|
|
|
|
resolver.fulfill(recordName)
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
failure: { (error) in
|
|
|
|
|
|
|
|
resolver.reject(error)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
return promise.retainUntilComplete()
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private class func saveRecordToCloud(record: CKRecord,
|
|
|
|
private class func saveRecordToCloud(record: CKRecord,
|
|
|
|
remainingRetries: Int,
|
|
|
|
remainingRetries: Int) -> Promise<String> {
|
|
|
|
success: @escaping (String) -> Void,
|
|
|
|
|
|
|
|
failure: @escaping (Error) -> Void) {
|
|
|
|
return Promise { resolver in
|
|
|
|
|
|
|
|
let saveOperation = CKModifyRecordsOperation(recordsToSave: [record ], recordIDsToDelete: nil)
|
|
|
|
let saveOperation = CKModifyRecordsOperation(recordsToSave: [record ], recordIDsToDelete: nil)
|
|
|
|
saveOperation.modifyRecordsCompletionBlock = { (records, recordIds, error) in
|
|
|
|
saveOperation.modifyRecordsCompletionBlock = { (records, recordIds, error) in
|
|
|
|
|
|
|
|
|
|
|
|
let outcome = outcomeForCloudKitError(error: error,
|
|
|
|
let outcome = outcomeForCloudKitError(error: error,
|
|
|
|
remainingRetries: remainingRetries,
|
|
|
|
remainingRetries: remainingRetries,
|
|
|
|
label: "Save Record")
|
|
|
|
label: "Save Record")
|
|
|
|
switch outcome {
|
|
|
|
switch outcome {
|
|
|
|
case .success:
|
|
|
|
case .success:
|
|
|
|
let recordName = record.recordID.recordName
|
|
|
|
let recordName = record.recordID.recordName
|
|
|
|
resolver.fulfill(recordName)
|
|
|
|
success(recordName)
|
|
|
|
case .failureDoNotRetry(let outcomeError):
|
|
|
|
case .failureDoNotRetry(let outcomeError):
|
|
|
|
resolver.reject(outcomeError)
|
|
|
|
failure(outcomeError)
|
|
|
|
case .failureRetryAfterDelay(let retryDelay):
|
|
|
|
case .failureRetryAfterDelay(let retryDelay):
|
|
|
|
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + retryDelay, execute: {
|
|
|
|
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + retryDelay, execute: {
|
|
|
|
saveRecordToCloud(record: record,
|
|
|
|
saveRecordToCloud(record: record,
|
|
|
|
remainingRetries: remainingRetries - 1)
|
|
|
|
remainingRetries: remainingRetries - 1,
|
|
|
|
.done { (recordName) in
|
|
|
|
success: success,
|
|
|
|
resolver.fulfill(recordName)
|
|
|
|
failure: failure)
|
|
|
|
}.catch { (error) in
|
|
|
|
})
|
|
|
|
resolver.reject(error)
|
|
|
|
case .failureRetryWithoutDelay:
|
|
|
|
}.retainUntilComplete()
|
|
|
|
DispatchQueue.global().async {
|
|
|
|
})
|
|
|
|
saveRecordToCloud(record: record,
|
|
|
|
case .failureRetryWithoutDelay:
|
|
|
|
remainingRetries: remainingRetries - 1,
|
|
|
|
DispatchQueue.global().async {
|
|
|
|
success: success,
|
|
|
|
saveRecordToCloud(record: record,
|
|
|
|
failure: failure)
|
|
|
|
remainingRetries: remainingRetries - 1)
|
|
|
|
|
|
|
|
.done { (recordName) in
|
|
|
|
|
|
|
|
resolver.fulfill(recordName)
|
|
|
|
|
|
|
|
}.catch { (error) in
|
|
|
|
|
|
|
|
resolver.reject(error)
|
|
|
|
|
|
|
|
}.retainUntilComplete()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
case .unknownItem:
|
|
|
|
|
|
|
|
owsFailDebug("unexpected CloudKit response.")
|
|
|
|
|
|
|
|
resolver.reject(invalidServiceResponseError())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case .unknownItem:
|
|
|
|
|
|
|
|
owsFailDebug("unexpected CloudKit response.")
|
|
|
|
|
|
|
|
failure(invalidServiceResponseError())
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
saveOperation.isAtomic = false
|
|
|
|
saveOperation.isAtomic = false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// These APIs are only available in iOS 9.3 and later.
|
|
|
|
// These APIs are only available in iOS 9.3 and later.
|
|
|
|
if #available(iOS 9.3, *) {
|
|
|
|
if #available(iOS 9.3, *) {
|
|
|
|
saveOperation.isLongLived = true
|
|
|
|
saveOperation.isLongLived = true
|
|
|
|
saveOperation.qualityOfService = .background
|
|
|
|
saveOperation.qualityOfService = .background
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
database().add(saveOperation)
|
|
|
|
database().add(saveOperation)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Compare:
|
|
|
|
// Compare:
|
|
|
@ -422,7 +420,7 @@ import PromiseKit
|
|
|
|
resolver.fulfill(record)
|
|
|
|
resolver.fulfill(record)
|
|
|
|
}.catch { (error) in
|
|
|
|
}.catch { (error) in
|
|
|
|
resolver.reject(error)
|
|
|
|
resolver.reject(error)
|
|
|
|
}
|
|
|
|
}.retainUntilComplete()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
case .failureRetryWithoutDelay:
|
|
|
|
case .failureRetryWithoutDelay:
|
|
|
|
DispatchQueue.global().async {
|
|
|
|
DispatchQueue.global().async {
|
|
|
@ -432,7 +430,7 @@ import PromiseKit
|
|
|
|
resolver.fulfill(record)
|
|
|
|
resolver.fulfill(record)
|
|
|
|
}.catch { (error) in
|
|
|
|
}.catch { (error) in
|
|
|
|
resolver.reject(error)
|
|
|
|
resolver.reject(error)
|
|
|
|
}
|
|
|
|
}.retainUntilComplete()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case .unknownItem:
|
|
|
|
case .unknownItem:
|
|
|
|
// Record not found.
|
|
|
|
// Record not found.
|
|
|
@ -440,7 +438,7 @@ import PromiseKit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
database().add(fetchOperation)
|
|
|
|
database().add(fetchOperation)
|
|
|
|
return promise.retainUntilComplete()
|
|
|
|
return promise
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
@objc
|
|
|
@ -701,13 +699,13 @@ import PromiseKit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
@objc
|
|
|
|
public class func checkCloudKitAccessObjc() -> AnyPromise {
|
|
|
|
public class func ensureCloudKitAccessObjc() -> AnyPromise {
|
|
|
|
return AnyPromise(checkCloudKitAccess())
|
|
|
|
return AnyPromise(ensureCloudKitAccess())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class func checkCloudKitAccess() -> Promise<Void> {
|
|
|
|
public class func ensureCloudKitAccess() -> Promise<Void> {
|
|
|
|
let (promise, resolver) = Promise<Void>.pending()
|
|
|
|
let (promise, resolver) = Promise<Void>.pending()
|
|
|
|
CKContainer.default().accountStatus(completionHandler: { (accountStatus, error) in
|
|
|
|
CKContainer.default().accountStatus { (accountStatus, error) in
|
|
|
|
if let error = error {
|
|
|
|
if let error = error {
|
|
|
|
Logger.error("Unknown error: \(String(describing: error)).")
|
|
|
|
Logger.error("Unknown error: \(String(describing: error)).")
|
|
|
|
resolver.reject(error)
|
|
|
|
resolver.reject(error)
|
|
|
@ -727,7 +725,7 @@ import PromiseKit
|
|
|
|
Logger.verbose("CloudKit access okay.")
|
|
|
|
Logger.verbose("CloudKit access okay.")
|
|
|
|
resolver.fulfill(())
|
|
|
|
resolver.fulfill(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return promise
|
|
|
|
return promise
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|