Implemented feed and folder restore so that undo works.

This commit is contained in:
Maurice Parker 2020-03-31 11:07:54 -05:00
parent 218df326f4
commit 1be5dc8a54
2 changed files with 67 additions and 17 deletions

View File

@ -180,7 +180,7 @@ final class CloudKitAccountDelegate: AccountDelegate {
case .failure(let error): case .failure(let error):
self.refreshProgress.completeTask() 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, Error>) -> Void) { func restoreWebFeed(for account: Account, feed: WebFeed, container: Container, completion: @escaping (Result<Void, Error>) -> 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<Folder, Error>) -> Void) { func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void) {
@ -298,6 +307,30 @@ final class CloudKitAccountDelegate: AccountDelegate {
case .success(let externalID): case .success(let externalID):
folder.externalID = externalID folder.externalID = externalID
account.addFolder(folder) 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): case .failure(let error):
completion(.failure(error)) completion(.failure(error))
} }

View File

@ -102,20 +102,28 @@ extension CloudKitZone {
return 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) { switch CloudKitZoneResult.resolve(error) {
case .success: case .success:
if let records = records { DispatchQueue.main.async {
completion(.success(records)) self?.refreshProgress?.completeTask()
} else { if let records = records {
completion(.failure(CloudKitZoneError.unknown)) completion(.success(records))
} else {
completion(.failure(CloudKitZoneError.unknown))
}
} }
case .retry(let timeToWait): case .retry(let timeToWait):
self.retryIfPossible(after: timeToWait) { self?.retryIfPossible(after: timeToWait) {
self.query(query, completion: completion) self?.query(query, completion: completion)
} }
default: 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) 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) { switch CloudKitZoneResult.resolve(error) {
case .success: case .success:
DispatchQueue.main.async { DispatchQueue.main.async {
self?.refreshProgress?.completeTask()
if let record = record { if let record = record {
completion(.success(record)) completion(.success(record))
} else { } else {
@ -139,11 +149,12 @@ extension CloudKitZone {
} }
} }
case .retry(let timeToWait): case .retry(let timeToWait):
self.retryIfPossible(after: timeToWait) { self?.retryIfPossible(after: timeToWait) {
self.fetch(externalID: externalID, completion: completion) self?.fetch(externalID: externalID, completion: completion)
} }
default: default:
DispatchQueue.main.async { DispatchQueue.main.async {
self?.refreshProgress?.completeTask()
completion(.failure(error!)) completion(.failure(error!))
} }
} }
@ -187,6 +198,7 @@ extension CloudKitZone {
switch CloudKitZoneResult.resolve(error) { switch CloudKitZoneResult.resolve(error) {
case .success: case .success:
DispatchQueue.main.async { DispatchQueue.main.async {
self.refreshProgress?.completeTask()
completion(.success(())) completion(.success(()))
} }
case .zoneNotFound: case .zoneNotFound:
@ -195,11 +207,15 @@ extension CloudKitZone {
case .success: case .success:
self.modify(recordsToSave: recordsToSave, recordIDsToDelete: recordIDsToDelete, completion: completion) self.modify(recordsToSave: recordsToSave, recordIDsToDelete: recordIDsToDelete, completion: completion)
case .failure(let error): case .failure(let error):
completion(.failure(error)) DispatchQueue.main.async {
self.refreshProgress?.completeTask()
completion(.failure(error))
}
} }
} }
case .userDeletedZone: case .userDeletedZone:
DispatchQueue.main.async { DispatchQueue.main.async {
self.refreshProgress?.completeTask()
completion(.failure(CloudKitZoneError.userDeletedZone)) completion(.failure(CloudKitZoneError.userDeletedZone))
} }
case .retry(let timeToWait): case .retry(let timeToWait):
@ -213,18 +229,18 @@ extension CloudKitZone {
} }
default: default:
DispatchQueue.main.async { DispatchQueue.main.async {
self.refreshProgress?.completeTask()
completion(.failure(error!)) completion(.failure(error!))
} }
} }
} }
refreshProgress?.addToNumberOfTasksAndRemaining(1)
database?.add(op) database?.add(op)
} }
func fetchChangesInZone(completion: @escaping (Result<Void, Error>) -> Void) { func fetchChangesInZone(completion: @escaping (Result<Void, Error>) -> Void) {
refreshProgress?.addToNumberOfTasksAndRemaining(1)
let zoneConfig = CKFetchRecordZoneChangesOperation.ZoneConfiguration() let zoneConfig = CKFetchRecordZoneChangesOperation.ZoneConfiguration()
zoneConfig.previousServerChangeToken = changeToken zoneConfig.previousServerChangeToken = changeToken
let op = CKFetchRecordZoneChangesOperation(recordZoneIDs: [Self.zoneID], configurationsByRecordZoneID: [Self.zoneID: zoneConfig]) let op = CKFetchRecordZoneChangesOperation(recordZoneIDs: [Self.zoneID], configurationsByRecordZoneID: [Self.zoneID: zoneConfig])
@ -279,6 +295,7 @@ extension CloudKitZone {
} }
} }
refreshProgress?.addToNumberOfTasksAndRemaining(1)
database?.add(op) database?.add(op)
} }