Add async/await version of API.

This commit is contained in:
Brent Simmons
2024-04-13 11:51:22 -07:00
parent 18e0c48bd8
commit 37fafe7bfe

View File

@@ -113,6 +113,15 @@ public extension CloudKitZone {
return CKRecord.ID(recordName: UUID().uuidString, zoneID: zoneID)
}
func delay(for seconds: Double) async {
await withCheckedContinuation { continuation in
self.retryIfPossible(after: seconds) {
continuation.resume()
}
}
}
func retryIfPossible(after: Double, block: @escaping () -> ()) {
let delayTime = DispatchTime.now() + after
DispatchQueue.main.asyncAfter(deadline: delayTime, execute: {
@@ -144,6 +153,21 @@ public extension CloudKitZone {
}
}
/// Retrieves the zone record for this zone only. If the record isn't found it will be created.
func fetchZoneRecord() async throws -> CKRecordZone? {
try await withCheckedThrowingContinuation { continuation in
self.fetchZoneRecord { result in
switch result {
case .success(let recordZone):
continuation.resume(returning: recordZone)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Retrieves the zone record for this zone only. If the record isn't found it will be created.
func fetchZoneRecord(completion: @escaping (Result<CKRecordZone?, Error>) -> Void) {
let op = CKFetchRecordZonesOperation(recordZoneIDs: [zoneID])
@@ -185,6 +209,21 @@ public extension CloudKitZone {
database?.add(op)
}
/// Creates the zone record
func createZoneRecord() async throws {
try await withCheckedThrowingContinuation { continuation in
self.createZoneRecord { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Creates the zone record
func createZoneRecord(completion: @escaping (Result<Void, Error>) -> Void) {
guard let database = database else {
@@ -219,7 +258,22 @@ public extension CloudKitZone {
}
}
}
/// Issue a CKQuery and return the resulting CKRecords.
func query(_ ckQuery: CKQuery, desiredKeys: [String]? = nil) async throws -> [CKRecord] {
try await withCheckedThrowingContinuation { continuation in
self.query(ckQuery, desiredKeys: desiredKeys) { result in
switch result {
case .success(let records):
continuation.resume(returning: records)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Issue a CKQuery and return the resulting CKRecords.
func query(_ ckQuery: CKQuery, desiredKeys: [String]? = nil, completion: @escaping (Result<[CKRecord], Error>) -> Void) {
var records = [CKRecord]()
@@ -280,6 +334,21 @@ public extension CloudKitZone {
database?.add(op)
}
/// Query CKRecords using a CKQuery Cursor
func query(cursor: CKQueryOperation.Cursor, desiredKeys: [String]? = nil, carriedRecords: [CKRecord]) async throws -> [CKRecord] {
try await withCheckedThrowingContinuation { continuation in
self.query(cursor: cursor, desiredKeys: desiredKeys, carriedRecords: carriedRecords) { result in
switch result {
case .success(let records):
continuation.resume(returning: records)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Query CKRecords using a CKQuery Cursor
func query(cursor: CKQueryOperation.Cursor, desiredKeys: [String]? = nil, carriedRecords: [CKRecord], completion: @escaping (Result<[CKRecord], Error>) -> Void) {
var records = carriedRecords
@@ -340,6 +409,20 @@ public extension CloudKitZone {
database?.add(op)
}
/// Fetch a CKRecord by using its externalID
func fetch(externalID: String?) async throws -> CKRecord {
try await withCheckedThrowingContinuation { continuation in
self.fetch(externalID: externalID) { result in
switch result {
case .success(let record):
continuation.resume(returning: record)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Fetch a CKRecord by using its externalID
func fetch(externalID: String?, completion: @escaping (Result<CKRecord, Error>) -> Void) {
@@ -393,16 +476,61 @@ public extension CloudKitZone {
}
}
/// Save the CKRecord
func save (_ record: CKRecord) async throws {
try await withCheckedThrowingContinuation { continuation in
self.save(record) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Save the CKRecord
func save(_ record: CKRecord, completion: @escaping (Result<Void, Error>) -> Void) {
modify(recordsToSave: [record], recordIDsToDelete: [], completion: completion)
}
/// Save the CKRecords
func save(_ records: [CKRecord]) async throws {
try await withCheckedThrowingContinuation { continuation in
self.save(records) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Save the CKRecords
func save(_ records: [CKRecord], completion: @escaping (Result<Void, Error>) -> Void) {
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]) async throws {
try await withCheckedThrowingContinuation { continuation in
self.saveIfNew(records) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// 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) {
let op = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: [CKRecord.ID]())
@@ -474,6 +602,21 @@ public extension CloudKitZone {
database?.add(op)
}
/// Save the CKSubscription
func save(_ subscription: CKSubscription) async throws -> CKSubscription {
try await withCheckedThrowingContinuation { continuation in
self.save(subscription) { result in
switch result {
case .success(let subscription):
continuation.resume(returning: subscription)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Save the CKSubscription
func save(_ subscription: CKSubscription, completion: @escaping (Result<CKSubscription, Error>) -> Void) {
database?.save(subscription) { [weak self] savedSubscription, error in
@@ -511,6 +654,21 @@ public extension CloudKitZone {
}
}
/// Delete CKRecords using a CKQuery
func delete(ckQuery: CKQuery) async throws {
try await withCheckedThrowingContinuation { continuation in
self.delete(ckQuery: ckQuery) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Delete CKRecords using a CKQuery
func delete(ckQuery: CKQuery, completion: @escaping (Result<Void, Error>) -> Void) {
@@ -548,6 +706,21 @@ public extension CloudKitZone {
database?.add(op)
}
/// Delete CKRecords using a CKQuery
func delete(cursor: CKQueryOperation.Cursor, carriedRecords: [CKRecord]) async throws {
try await withCheckedThrowingContinuation { continuation in
self.delete(cursor: cursor, carriedRecords: carriedRecords) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Delete CKRecords using a CKQuery
func delete(cursor: CKQueryOperation.Cursor, carriedRecords: [CKRecord], completion: @escaping (Result<Void, Error>) -> Void) {
@@ -579,16 +752,61 @@ public extension CloudKitZone {
database?.add(op)
}
/// Delete a CKRecord using its recordID
func delete(recordID: CKRecord.ID) async throws {
try await withCheckedThrowingContinuation { continuation in
self.delete(recordID: recordID) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Delete a CKRecord using its recordID
func delete(recordID: CKRecord.ID, completion: @escaping (Result<Void, Error>) -> Void) {
modify(recordsToSave: [], recordIDsToDelete: [recordID], completion: completion)
}
/// Delete CKRecords
func delete(recordIDs: [CKRecord.ID]) async throws {
try await withCheckedThrowingContinuation { continuation in
self.delete(recordIDs: recordIDs) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Delete CKRecords
func delete(recordIDs: [CKRecord.ID], completion: @escaping (Result<Void, Error>) -> Void) {
modify(recordsToSave: [], recordIDsToDelete: recordIDs, completion: completion)
}
/// Delete a CKRecord using its externalID
func delete(externalID: String?) async throws {
try await withCheckedThrowingContinuation { continuation in
self.delete(externalID: externalID) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Delete a CKRecord using its externalID
func delete(externalID: String?, completion: @escaping (Result<Void, Error>) -> Void) {
guard let externalID = externalID else {
@@ -600,6 +818,21 @@ public extension CloudKitZone {
modify(recordsToSave: [], recordIDsToDelete: [recordID], completion: completion)
}
/// Delete a CKSubscription
func delete(subscriptionID: String) async throws {
try await withCheckedThrowingContinuation { continuation in
self.delete(subscriptionID: subscriptionID) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Delete a CKSubscription
func delete(subscriptionID: String, completion: @escaping (Result<Void, Error>) -> Void) {
database?.delete(withSubscriptionID: subscriptionID) { [weak self] _, error in
@@ -626,6 +859,21 @@ public extension CloudKitZone {
}
}
/// Modify and delete the supplied CKRecords and CKRecord.IDs
func modify(recordsToSave: [CKRecord], recordIDsToDelete: [CKRecord.ID]) async throws {
try await withCheckedThrowingContinuation { continuation in
self.modify(recordsToSave: recordsToSave, recordIDsToDelete: recordIDsToDelete) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Modify and delete the supplied CKRecords and CKRecord.IDs
func modify(recordsToSave: [CKRecord], recordIDsToDelete: [CKRecord.ID], completion: @escaping (Result<Void, Error>) -> Void) {
guard !(recordsToSave.isEmpty && recordIDsToDelete.isEmpty) else {
@@ -735,6 +983,21 @@ public extension CloudKitZone {
database?.add(op)
}
/// Fetch all the changes in the CKZone since the last time we checked
@MainActor func fetchChangesInZone() async throws {
try await withCheckedThrowingContinuation { continuation in
self.fetchChangesInZone { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
/// Fetch all the changes in the CKZone since the last time we checked
@MainActor func fetchChangesInZone(completion: @escaping (Result<Void, Error>) -> Void) {
@@ -819,5 +1082,4 @@ public extension CloudKitZone {
database?.add(op)
}
}