diff --git a/Account/Sources/Account/AccountDelegates/LocalAccountDelegate.swift b/Account/Sources/Account/AccountDelegates/LocalAccountDelegate.swift index 7b31b61c1..2e5f29386 100644 --- a/Account/Sources/Account/AccountDelegates/LocalAccountDelegate.swift +++ b/Account/Sources/Account/AccountDelegates/LocalAccountDelegate.swift @@ -16,6 +16,7 @@ import Secrets import Core import CommonErrors import FeedFinder +import LocalAccount public enum LocalAccountDelegateError: String, Error { case invalidParameter = "An invalid parameter was used." diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift index 51c5c568c..605eca048 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift @@ -20,6 +20,7 @@ import Core import CloudKitExtras import CommonErrors import FeedFinder +import LocalAccount enum CloudKitAccountDelegateError: LocalizedError { case invalidParameter @@ -836,59 +837,61 @@ private extension CloudKitAccountDelegate { } return } - + if account.hasFeed(withURL: bestFeedSpecifier.urlString) { self.refreshProgress.completeTasks(4) completion(.failure(AccountError.createErrorAlreadySubscribed)) return } - + let feed = account.createFeed(with: nil, url: url.absoluteString, feedID: url.absoluteString, homePageURL: nil) feed.editedName = editedName container.addFeed(feed) - + InitialFeedDownloader.download(url) { parsedFeed in - self.refreshProgress.completeTask() - - if let parsedFeed { - - Task { @MainActor in - - do { - try await account.update(feed: feed, with: parsedFeed) - - self.accountZone.createFeed(url: bestFeedSpecifier.urlString, - name: parsedFeed.title, - editedName: editedName, - homePageURL: parsedFeed.homePageURL, - container: container) { result in - - self.refreshProgress.completeTask() - switch result { - case .success(let externalID): - feed.externalID = externalID - self.sendNewArticlesToTheCloud(account, feed) - completion(.success(feed)) - case .failure(let error): - container.removeFeed(feed) - self.refreshProgress.completeTasks(2) - completion(.failure(error)) + MainActor.assumeIsolated { + self.refreshProgress.completeTask() + + if let parsedFeed { + + Task { @MainActor in + + do { + try await account.update(feed: feed, with: parsedFeed) + + self.accountZone.createFeed(url: bestFeedSpecifier.urlString, + name: parsedFeed.title, + editedName: editedName, + homePageURL: parsedFeed.homePageURL, + container: container) { result in + + self.refreshProgress.completeTask() + switch result { + case .success(let externalID): + feed.externalID = externalID + self.sendNewArticlesToTheCloud(account, feed) + completion(.success(feed)) + case .failure(let error): + container.removeFeed(feed) + self.refreshProgress.completeTasks(2) + completion(.failure(error)) + } + } - + } catch { + container.removeFeed(feed) + self.refreshProgress.completeTasks(3) + completion(.failure(error)) } - } catch { - container.removeFeed(feed) - self.refreshProgress.completeTasks(3) - completion(.failure(error)) } + } else { + self.refreshProgress.completeTasks(3) + container.removeFeed(feed) + completion(.failure(AccountError.createErrorNotFound)) } - } else { - self.refreshProgress.completeTasks(3) - container.removeFeed(feed) - completion(.failure(AccountError.createErrorNotFound)) - } + } } - + case .failure: self.refreshProgress.completeTasks(3) if validateFeed { diff --git a/LocalAccount/Sources/LocalAccount/InitialFeedDownloader.swift b/LocalAccount/Sources/LocalAccount/InitialFeedDownloader.swift index df281c01d..c2b38a2dd 100644 --- a/LocalAccount/Sources/LocalAccount/InitialFeedDownloader.swift +++ b/LocalAccount/Sources/LocalAccount/InitialFeedDownloader.swift @@ -21,7 +21,7 @@ public struct InitialFeedDownloader { } } - @MainActor static func download(_ url: URL,_ completion: @escaping @Sendable (_ parsedFeed: ParsedFeed?) -> Void) { + @MainActor public static func download(_ url: URL,_ completion: @escaping @Sendable (_ parsedFeed: ParsedFeed?) -> Void) { downloadUsingCache(url) { (data, response, error) in guard let data = data else {