diff --git a/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift b/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift index c33330707..90443596c 100644 --- a/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift @@ -180,7 +180,7 @@ final class CloudKitAccountDelegate: AccountDelegate { case .failure(let error): self.refreshProgress.completeTask() - completion(.failure(error)) // TODO: need to handle userDeletedZone + completion(.failure(error)) } } @@ -244,7 +244,16 @@ final class CloudKitAccountDelegate: AccountDelegate { } func restoreWebFeed(for account: Account, feed: WebFeed, container: Container, completion: @escaping (Result) -> Void) { - addWebFeed(for: account, with: feed, to: container, completion: completion) + accountZone.createWebFeed(url: feed.url, editedName: feed.editedName, container: container) { result in + switch result { + case .success(let externalID): + feed.externalID = externalID + container.addWebFeed(feed) + completion(.success(())) + case .failure(let error): + completion(.failure(error)) + } + } } func createFolder(for account: Account, name: String, completion: @escaping (Result) -> Void) { @@ -298,6 +307,30 @@ final class CloudKitAccountDelegate: AccountDelegate { case .success(let externalID): folder.externalID = externalID account.addFolder(folder) + + let group = DispatchGroup() + for feed in folder.topLevelWebFeeds { + + folder.topLevelWebFeeds.remove(feed) + + group.enter() + self.restoreWebFeed(for: account, feed: feed, container: folder) { result in + group.leave() + switch result { + case .success: + break + case .failure(let error): + os_log(.error, log: self.log, "Restore folder feed error: %@.", error.localizedDescription) + } + } + + } + + group.notify(queue: DispatchQueue.main) { + account.addFolder(folder) + completion(.success(())) + } + case .failure(let error): completion(.failure(error)) } diff --git a/Frameworks/Account/CloudKit/CloudKitZone.swift b/Frameworks/Account/CloudKit/CloudKitZone.swift index 83dcff1a1..2ed4486f2 100644 --- a/Frameworks/Account/CloudKit/CloudKitZone.swift +++ b/Frameworks/Account/CloudKit/CloudKitZone.swift @@ -102,20 +102,28 @@ extension CloudKitZone { return } - database.perform(query, inZoneWith: Self.zoneID) { records, error in + refreshProgress?.addToNumberOfTasksAndRemaining(1) + + database.perform(query, inZoneWith: Self.zoneID) { [weak self] records, error in switch CloudKitZoneResult.resolve(error) { case .success: - if let records = records { - completion(.success(records)) - } else { - completion(.failure(CloudKitZoneError.unknown)) + DispatchQueue.main.async { + self?.refreshProgress?.completeTask() + if let records = records { + completion(.success(records)) + } else { + completion(.failure(CloudKitZoneError.unknown)) + } } case .retry(let timeToWait): - self.retryIfPossible(after: timeToWait) { - self.query(query, completion: completion) + self?.retryIfPossible(after: timeToWait) { + self?.query(query, completion: completion) } default: - completion(.failure(error!)) + DispatchQueue.main.async { + self?.refreshProgress?.completeTask() + completion(.failure(error!)) + } } } } @@ -128,10 +136,12 @@ extension CloudKitZone { let recordID = CKRecord.ID(recordName: externalID, zoneID: Self.zoneID) - database?.fetch(withRecordID: recordID) { record, error in + refreshProgress?.addToNumberOfTasksAndRemaining(1) + database?.fetch(withRecordID: recordID) { [weak self] record, error in switch CloudKitZoneResult.resolve(error) { case .success: DispatchQueue.main.async { + self?.refreshProgress?.completeTask() if let record = record { completion(.success(record)) } else { @@ -139,11 +149,12 @@ extension CloudKitZone { } } case .retry(let timeToWait): - self.retryIfPossible(after: timeToWait) { - self.fetch(externalID: externalID, completion: completion) + self?.retryIfPossible(after: timeToWait) { + self?.fetch(externalID: externalID, completion: completion) } default: DispatchQueue.main.async { + self?.refreshProgress?.completeTask() completion(.failure(error!)) } } @@ -187,6 +198,7 @@ extension CloudKitZone { switch CloudKitZoneResult.resolve(error) { case .success: DispatchQueue.main.async { + self.refreshProgress?.completeTask() completion(.success(())) } case .zoneNotFound: @@ -195,11 +207,15 @@ extension CloudKitZone { case .success: self.modify(recordsToSave: recordsToSave, recordIDsToDelete: recordIDsToDelete, completion: completion) case .failure(let error): - completion(.failure(error)) + DispatchQueue.main.async { + self.refreshProgress?.completeTask() + completion(.failure(error)) + } } } case .userDeletedZone: DispatchQueue.main.async { + self.refreshProgress?.completeTask() completion(.failure(CloudKitZoneError.userDeletedZone)) } case .retry(let timeToWait): @@ -213,18 +229,18 @@ extension CloudKitZone { } default: DispatchQueue.main.async { + self.refreshProgress?.completeTask() completion(.failure(error!)) } } } - + + refreshProgress?.addToNumberOfTasksAndRemaining(1) database?.add(op) } func fetchChangesInZone(completion: @escaping (Result) -> Void) { - refreshProgress?.addToNumberOfTasksAndRemaining(1) - let zoneConfig = CKFetchRecordZoneChangesOperation.ZoneConfiguration() zoneConfig.previousServerChangeToken = changeToken let op = CKFetchRecordZoneChangesOperation(recordZoneIDs: [Self.zoneID], configurationsByRecordZoneID: [Self.zoneID: zoneConfig]) @@ -279,6 +295,7 @@ extension CloudKitZone { } } + refreshProgress?.addToNumberOfTasksAndRemaining(1) database?.add(op) }