Convert addFeed to async await.

This commit is contained in:
Brent Simmons 2024-03-28 08:24:35 -07:00
parent 0ce67a3f3f
commit c5441bddc3
11 changed files with 163 additions and 121 deletions

View File

@ -607,8 +607,9 @@ public enum FetchType {
return feed return feed
} }
public func addFeed(_ feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) { public func addFeed(_ feed: Feed, to container: Container) async throws {
delegate.addFeed(for: self, with: feed, to: container, completion: completion)
try await delegate.addFeed(for: self, with: feed, to: container)
} }
public func createFeed(url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result<Feed, Error>) -> Void) { public func createFeed(url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result<Feed, Error>) -> Void) {

View File

@ -38,7 +38,7 @@ import Secrets
func createFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result<Feed, Error>) -> Void) func createFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result<Feed, Error>) -> Void)
func renameFeed(for account: Account, with feed: Feed, to name: String) async throws func renameFeed(for account: Account, with feed: Feed, to name: String) async throws
func addFeed(for account: Account, with: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) func addFeed(for account: Account, with: Feed, to container: Container) async throws
func removeFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result<Void, Error>) -> Void) func removeFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result<Void, Error>) -> Void)
func moveFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result<Void, Error>) -> Void) func moveFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result<Void, Error>) -> Void)

View File

@ -321,7 +321,22 @@ enum CloudKitAccountDelegateError: LocalizedError {
} }
} }
func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) { func addFeed(for account: Account, with feed: Feed, to container: any Container) async throws {
try await withCheckedThrowingContinuation { continuation in
self.addFeed(for: account, with: feed, to: container) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
private func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
refreshProgress.addToNumberOfTasksAndRemaining(1) refreshProgress.addToNumberOfTasksAndRemaining(1)
accountZone.addFeed(feed, to: container) { result in accountZone.addFeed(feed, to: container) { result in
self.refreshProgress.completeTask() self.refreshProgress.completeTask()

View File

@ -564,7 +564,22 @@ final class FeedbinAccountDelegate: AccountDelegate {
} }
} }
func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) { func addFeed(for account: Account, with feed: Feed, to container: any Container) async throws {
try await withCheckedThrowingContinuation { continuation in
self.addFeed(for: account, with: feed, to: container) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
private func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
if let folder = container as? Folder, let feedID = Int(feed.feedID) { if let folder = container as? Folder, let feedID = Int(feed.feedID) {
refreshProgress.addToNumberOfTasksAndRemaining(1) refreshProgress.addToNumberOfTasksAndRemaining(1)
@ -614,11 +629,13 @@ final class FeedbinAccountDelegate: AccountDelegate {
private func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) { private func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
if let existingFeed = account.existingFeed(withURL: feed.url) { if let existingFeed = account.existingFeed(withURL: feed.url) {
account.addFeed(existingFeed, to: container) { result in
switch result { Task { @MainActor in
case .success:
do {
try await account.addFeed(existingFeed, to: container)
completion(.success(())) completion(.success(()))
case .failure(let error): } catch {
completion(.failure(error)) completion(.failure(error))
} }
} }
@ -632,7 +649,6 @@ final class FeedbinAccountDelegate: AccountDelegate {
} }
} }
} }
} }
func restoreFolder(for account: Account, folder: Folder) async throws { func restoreFolder(for account: Account, folder: Folder) async throws {
@ -1191,33 +1207,21 @@ private extension FeedbinAccountDelegate {
func createFeed( account: Account, subscription sub: FeedbinSubscription, name: String?, container: Container, completion: @escaping (Result<Feed, Error>) -> Void) { func createFeed( account: Account, subscription sub: FeedbinSubscription, name: String?, container: Container, completion: @escaping (Result<Feed, Error>) -> Void) {
DispatchQueue.main.async { Task { @MainActor in
let feed = account.createFeed(with: sub.name, url: sub.url, feedID: String(sub.feedID), homePageURL: sub.homePageURL) let feed = account.createFeed(with: sub.name, url: sub.url, feedID: String(sub.feedID), homePageURL: sub.homePageURL)
feed.externalID = String(sub.subscriptionID) feed.externalID = String(sub.subscriptionID)
feed.iconURL = sub.jsonFeed?.icon feed.iconURL = sub.jsonFeed?.icon
feed.faviconURL = sub.jsonFeed?.favicon feed.faviconURL = sub.jsonFeed?.favicon
account.addFeed(feed, to: container) { result in
switch result {
case .success:
if let name = name {
Task { @MainActor in
do { do {
try await account.renameFeed(feed, to: name) try await account.addFeed(feed, to: container)
if let name {
try await self.renameFeed(for: account, with: feed, to: name)
}
self.initialFeedDownload(account: account, feed: feed, completion: completion) self.initialFeedDownload(account: account, feed: feed, completion: completion)
} catch { } catch {
completion(.failure(error)) completion(.failure(error))
}
}
} else {
self.initialFeedDownload(account: account, feed: feed, completion: completion)
}
case .failure(let error):
completion(.failure(error))
}
} }
} }
} }

View File

@ -494,7 +494,22 @@ final class FeedlyAccountDelegate: AccountDelegate {
feed.editedName = name feed.editedName = name
} }
@MainActor func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) { func addFeed(for account: Account, with feed: Feed, to container: any Container) async throws {
try await withCheckedThrowingContinuation { continuation in
self.addFeed(for: account, with: feed, to: container) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
do { do {
guard let credentials = credentials else { guard let credentials = credentials else {
@ -594,12 +609,14 @@ final class FeedlyAccountDelegate: AccountDelegate {
} }
private func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) { private func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
if let existingFeed = account.existingFeed(withURL: feed.url) { if let existingFeed = account.existingFeed(withURL: feed.url) {
account.addFeed(existingFeed, to: container) { result in
switch result { Task { @MainActor in
case .success: do {
try await account.addFeed(existingFeed, to: container)
completion(.success(())) completion(.success(()))
case .failure(let error): } catch {
completion(.failure(error)) completion(.failure(error))
} }
} }

View File

@ -107,9 +107,9 @@ final class LocalAccountDelegate: AccountDelegate {
completion(.success(())) completion(.success(()))
} }
func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) { func addFeed(for account: Account, with feed: Feed, to container: any Container) async throws {
container.addFeed(feed) container.addFeed(feed)
completion(.success(()))
} }
func restoreFeed(for account: Account, feed: Feed, container: any Container) async throws { func restoreFeed(for account: Account, feed: Feed, container: any Container) async throws {

View File

@ -434,32 +434,21 @@ extension NewsBlurAccountDelegate {
return return
} }
DispatchQueue.main.async { Task { @MainActor in
let feed = account.createFeed(with: feed.name, url: feed.feedURL, feedID: String(feed.feedID), homePageURL: feed.homePageURL) let feed = account.createFeed(with: feed.name, url: feed.feedURL, feedID: String(feed.feedID), homePageURL: feed.homePageURL)
feed.externalID = String(feed.feedID) feed.externalID = String(feed.feedID)
feed.faviconURL = feed.faviconURL feed.faviconURL = feed.faviconURL
account.addFeed(feed, to: container) { result in
switch result {
case .success:
if let name = name {
Task { @MainActor in
do { do {
try await account.renameFeed(feed, to: name) try await account.addFeed(feed, to: container)
if let name {
try await self.renameFeed(for: account, with: feed, to: name)
}
self.initialFeedDownload(account: account, feed: feed, completion: completion) self.initialFeedDownload(account: account, feed: feed, completion: completion)
} catch { } catch {
completion(.failure(error)) completion(.failure(error))
} }
} }
} else {
self.initialFeedDownload(account: account, feed: feed, completion: completion)
}
case .failure(let error):
completion(.failure(error))
}
}
}
} }
func downloadFeed(account: Account, feed: Feed, page: Int, completion: @escaping (Result<Void, Error>) -> Void) { func downloadFeed(account: Account, feed: Feed, page: Int, completion: @escaping (Result<Void, Error>) -> Void) {

View File

@ -576,7 +576,22 @@ final class NewsBlurAccountDelegate: AccountDelegate {
} }
} }
func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> ()) { func addFeed(for account: Account, with feed: Feed, to container: any Container) async throws {
try await withCheckedThrowingContinuation { continuation in
self.addFeed(for: account, with: feed, to: container) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
private func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> ()) {
guard let folder = container as? Folder else { guard let folder = container as? Folder else {
DispatchQueue.main.async { DispatchQueue.main.async {
if let account = container as? Account { if let account = container as? Account {
@ -643,11 +658,12 @@ final class NewsBlurAccountDelegate: AccountDelegate {
private func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result<Void, Error>) -> ()) { private func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result<Void, Error>) -> ()) {
if let existingFeed = account.existingFeed(withURL: feed.url) { if let existingFeed = account.existingFeed(withURL: feed.url) {
account.addFeed(existingFeed, to: container) { result in Task { @MainActor in
switch result {
case .success: do {
try await account.addFeed(existingFeed, to: container)
completion(.success(())) completion(.success(()))
case .failure(let error): } catch {
completion(.failure(error)) completion(.failure(error))
} }
} }

View File

@ -618,7 +618,22 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
} }
} }
func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) { func addFeed(for account: Account, with feed: Feed, to container: any Container) async throws {
try await withCheckedThrowingContinuation { continuation in
self.addFeed(for: account, with: feed, to: container) { result in
switch result {
case .success:
continuation.resume()
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
private func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
if let folder = container as? Folder, let feedExternalID = feed.externalID { if let folder = container as? Folder, let feedExternalID = feed.externalID {
refreshProgress.addToNumberOfTasksAndRemaining(1) refreshProgress.addToNumberOfTasksAndRemaining(1)
caller.createTagging(subscriptionID: feedExternalID, tagName: folder.name ?? "") { result in caller.createTagging(subscriptionID: feedExternalID, tagName: folder.name ?? "") { result in
@ -666,11 +681,12 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
private func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) { private func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
if let existingFeed = account.existingFeed(withURL: feed.url) { if let existingFeed = account.existingFeed(withURL: feed.url) {
account.addFeed(existingFeed, to: container) { result in Task { @MainActor in
switch result {
case .success: do {
try await account.addFeed(existingFeed, to: container)
completion(.success(())) completion(.success(()))
case .failure(let error): } catch {
completion(.failure(error)) completion(.failure(error))
} }
} }
@ -1087,33 +1103,21 @@ private extension ReaderAPIAccountDelegate {
func createFeed( account: Account, subscription sub: ReaderAPISubscription, name: String?, container: Container, completion: @escaping (Result<Feed, Error>) -> Void) { func createFeed( account: Account, subscription sub: ReaderAPISubscription, name: String?, container: Container, completion: @escaping (Result<Feed, Error>) -> Void) {
DispatchQueue.main.async { Task { @MainActor in
let feed = account.createFeed(with: sub.name, url: sub.url, feedID: String(sub.feedID), homePageURL: sub.homePageURL) let feed = account.createFeed(with: sub.name, url: sub.url, feedID: String(sub.feedID), homePageURL: sub.homePageURL)
feed.externalID = String(sub.feedID) feed.externalID = String(sub.feedID)
account.addFeed(feed, to: container) { result in do {
switch result { try await account.addFeed(feed, to: container)
case .success: if let name {
if let name = name { try await self.renameFeed(for: account, with: feed, to: name)
self.renameFeed(for: account, with: feed, to: name) { result in }
switch result {
case .success:
self.initialFeedDownload(account: account, feed: feed, completion: completion) self.initialFeedDownload(account: account, feed: feed, completion: completion)
case .failure(let error): } catch {
completion(.failure(error)) completion(.failure(error))
} }
} }
} else {
self.initialFeedDownload(account: account, feed: feed, completion: completion)
}
case .failure(let error):
completion(.failure(error))
}
}
}
} }
func initialFeedDownload( account: Account, feed: Feed, completion: @escaping (Result<Feed, Error>) -> Void) { func initialFeedDownload( account: Account, feed: Feed, completion: @escaping (Result<Feed, Error>) -> Void) {

View File

@ -314,11 +314,10 @@ private extension SidebarOutlineDataSource {
return return
} }
destination.account?.addFeed(feed, to: destination) { result in Task { @MainActor in
switch result { do {
case .success: try await destination.account?.addFeed(feed, to: destination)
break } catch {
case .failure(let error):
NSApplication.shared.presentError(error) NSApplication.shared.presentError(error)
} }
} }
@ -351,11 +350,11 @@ private extension SidebarOutlineDataSource {
} }
if let existingFeed = destinationAccount.existingFeed(withURL: feed.url) { if let existingFeed = destinationAccount.existingFeed(withURL: feed.url) {
destinationAccount.addFeed(existingFeed, to: destinationContainer) { result in
switch result { Task { @MainActor in
case .success: do {
break try await destinationAccount.addFeed(existingFeed, to: destinationContainer)
case .failure(let error): } catch {
NSApplication.shared.presentError(error) NSApplication.shared.presentError(error)
} }
} }
@ -437,14 +436,7 @@ private extension SidebarOutlineDataSource {
for feed in folder.topLevelFeeds { for feed in folder.topLevelFeeds {
if let existingFeed = destinationAccount.existingFeed(withURL: feed.url) { if let existingFeed = destinationAccount.existingFeed(withURL: feed.url) {
destinationAccount.addFeed(existingFeed, to: destinationFolder) { result in try await destinationAccount.addFeed(existingFeed, to: destinationFolder)
switch result {
case .success:
break
case .failure(let error):
NSApplication.shared.presentError(error)
}
}
} else { } else {
destinationAccount.createFeed(url: feed.url, name: feed.nameForDisplay, container: destinationFolder, validateFeed: false) { result in destinationAccount.createFeed(url: feed.url, name: feed.nameForDisplay, container: destinationFolder, validateFeed: false) { result in
switch result { switch result {

View File

@ -120,9 +120,12 @@ extension SidebarViewController: UITableViewDropDelegate {
if let existingFeed = destinationContainer.account?.existingFeed(withURL: feed.url) { if let existingFeed = destinationContainer.account?.existingFeed(withURL: feed.url) {
BatchUpdate.shared.start() BatchUpdate.shared.start()
destinationContainer.account?.addFeed(existingFeed, to: destinationContainer) { result in
switch result { Task { @MainActor in
case .success:
do {
try await destinationContainer.account?.addFeed(existingFeed, to: destinationContainer)
sourceContainer.account?.removeFeed(feed, from: sourceContainer) { result in sourceContainer.account?.removeFeed(feed, from: sourceContainer) { result in
BatchUpdate.shared.end() BatchUpdate.shared.end()
switch result { switch result {
@ -132,7 +135,8 @@ extension SidebarViewController: UITableViewDropDelegate {
self.presentError(error) self.presentError(error)
} }
} }
case .failure(let error):
} catch {
BatchUpdate.shared.end() BatchUpdate.shared.end()
self.presentError(error) self.presentError(error)
} }