From 1439e29d64066d64a33600355b335309c607f3bd Mon Sep 17 00:00:00 2001 From: Duong Thai Date: Fri, 15 Mar 2024 10:41:43 +0700 Subject: [PATCH] fix: concurrency code for RSSTools --- Packages/RSS/Sources/RSS/RSSTools.swift | 32 ++++++++++++++----- .../RSS/Sources/RSS/Views/RSSAddNewFeed.swift | 10 ++++-- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/Packages/RSS/Sources/RSS/RSSTools.swift b/Packages/RSS/Sources/RSS/RSSTools.swift index 2b705264..fbeb1e55 100644 --- a/Packages/RSS/Sources/RSS/RSSTools.swift +++ b/Packages/RSS/Sources/RSS/RSSTools.swift @@ -191,7 +191,7 @@ enum RSSTools { } @MainActor - static func load(feedURL: URL) async -> RSSFeed? { + static func load(feedURL: URL) async -> Void? { let sendableFeed = await Task.detached { await RSSTools.getFeedData(from: feedURL) }.value @@ -203,15 +203,31 @@ enum RSSTools { await sendableFeed.getSendableItemData() }.value - return await backgroundContext.perform { - let rssFeed = RSSFeed(context: backgroundContext, sendableData: sendableFeed) + let rssFeed = RSSFeed(context: backgroundContext, sendableData: sendableFeed) - let rssItems = sendableItems.compactMap { - RSSItem(context: backgroundContext, sendableData: $0) - } - rssFeed.items = NSSet(array: rssItems) - return rssFeed + let rssItems = sendableItems.compactMap { + RSSItem(context: backgroundContext, sendableData: $0) } + for item in rssItems { item.feed = rssFeed } + + return try? backgroundContext.save() + } + + @MainActor + static func fetchFeed(url: URL) async -> RSSFeed? { + let request: NSFetchRequest = { + let request = RSSFeed.fetchRequest() + request.fetchLimit = 1 + request.predicate = NSPredicate(format: "%K = %@", + #keyPath(RSSFeed.feedURL), + url as CVarArg) + request.relationshipKeyPathsForPrefetching = ["items"] + return request + }() + + let context = RSSDataController.shared.viewContext + guard let feed = (try? context.fetch(request))?.first else { return nil } + return feed } @MainActor diff --git a/Packages/RSS/Sources/RSS/Views/RSSAddNewFeed.swift b/Packages/RSS/Sources/RSS/Views/RSSAddNewFeed.swift index 001d3bfa..f645325c 100644 --- a/Packages/RSS/Sources/RSS/Views/RSSAddNewFeed.swift +++ b/Packages/RSS/Sources/RSS/Views/RSSAddNewFeed.swift @@ -66,10 +66,14 @@ public struct RSSAddNewFeed: View { feed?.managedObjectContext?.rollback() downloadingTask = Task { - let rssFeed = await RSSTools.load(feedURL: url) + guard let _ = await RSSTools.load(feedURL: url), + let rssFeed = await RSSTools.fetchFeed(url: url) + else { + self.state = .noData(url: url) + return + } if Task.isCancelled { return } - if let rssFeed { self.state = .downloaded(feed: rssFeed, url: url) } - else { self.state = .noData(url: url) } + self.state = .downloaded(feed: rssFeed, url: url) } case .downloaded(let feed, _): self.feed = feed