@@ -49,7 +49,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
4949
5050 private lazy var navigationController = UINavigationController (
5151 rootViewController: FeedUIComposer . feedComposedWith (
52- feedLoader: makeRemoteFeedLoaderWithLocalFallback ,
52+ feedLoader: loadRemoteFeedWithLocalFallback ,
5353 imageLoader: loadLocalImageWithRemoteFallback,
5454 selection: showComments) )
5555
@@ -96,44 +96,59 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
9696 }
9797 }
9898
99- private func makeRemoteFeedLoaderWithLocalFallback( ) -> AnyPublisher < Paginated < FeedImage > , Error > {
100- makeRemoteFeedLoader ( )
101- . receive ( on: scheduler)
102- . caching ( to: localFeedLoader)
103- . fallback ( to: localFeedLoader. loadPublisher)
104- . map ( makeFirstPage)
105- . eraseToAnyPublisher ( )
99+ private func loadRemoteFeedWithLocalFallback( ) async throws -> Paginated < FeedImage > {
100+ do {
101+ let feed = try await loadAndCacheRemoteFeed ( )
102+ return makeFirstPage ( items: feed)
103+ } catch {
104+ let feed = try await loadLocalFeed ( )
105+ return makeFirstPage ( items: feed)
106+ }
106107 }
107108
108- private func makeRemoteLoadMoreLoader( last: FeedImage ? ) -> AnyPublisher < Paginated < FeedImage > , Error > {
109- localFeedLoader. loadPublisher ( )
110- . zip ( makeRemoteFeedLoader ( after: last) )
111- . map { ( cachedItems, newItems) in
112- ( cachedItems + newItems, newItems. last)
113- }
114- . map ( makePage)
115- . receive ( on: scheduler)
116- . caching ( to: localFeedLoader)
117- . subscribe ( on: scheduler)
118- . eraseToAnyPublisher ( )
109+ private func loadAndCacheRemoteFeed( ) async throws -> [ FeedImage ] {
110+ let feed = try await loadRemoteFeed ( )
111+ await store. schedule { [ store] in
112+ let localFeedLoader = LocalFeedLoader ( store: store, currentDate: Date . init)
113+ try ? localFeedLoader. save ( feed)
114+ }
115+ return feed
116+ }
117+
118+ private func loadLocalFeed( ) async throws -> [ FeedImage ] {
119+ try await store. schedule { [ store] in
120+ let localFeedLoader = LocalFeedLoader ( store: store, currentDate: Date . init)
121+ return try localFeedLoader. load ( )
122+ }
119123 }
120124
121- private func makeRemoteFeedLoader ( after: FeedImage ? = nil ) -> AnyPublisher < [ FeedImage ] , Error > {
125+ private func loadRemoteFeed ( after: FeedImage ? = nil ) async throws -> [ FeedImage ] {
122126 let url = FeedEndpoint . get ( after: after) . url ( baseURL: baseURL)
127+ let ( data, response) = try await httpClient. get ( from: url)
128+ return try FeedItemsMapper . map ( data, from: response)
129+ }
130+
131+ private func loadMoreRemoteFeed( last: FeedImage ? ) async throws -> Paginated < FeedImage > {
132+ async let cachedItems = try await loadLocalFeed ( )
133+ async let newItems = try await loadRemoteFeed ( after: last)
134+
135+ let items = try await cachedItems + newItems
136+
137+ await store. schedule { [ store] in
138+ let localFeedLoader = LocalFeedLoader ( store: store, currentDate: Date . init)
139+ try ? localFeedLoader. save ( items)
140+ }
123141
124- return httpClient
125- . getPublisher ( url: url)
126- . tryMap ( FeedItemsMapper . map)
127- . eraseToAnyPublisher ( )
142+ return try await makePage ( items: items, last: newItems. last)
128143 }
129144
130145 private func makeFirstPage( items: [ FeedImage ] ) -> Paginated < FeedImage > {
131146 makePage ( items: items, last: items. last)
132147 }
133148
134149 private func makePage( items: [ FeedImage ] , last: FeedImage ? ) -> Paginated < FeedImage > {
135- Paginated ( items: items, loadMorePublisher : last. map { last in
136- { self . makeRemoteLoadMoreLoader ( last: last) }
150+ Paginated ( items: items, loadMore : last. map { last in
151+ { @ MainActor @ Sendable in try await self . loadMoreRemoteFeed ( last: last) }
137152 } )
138153 }
139154
0 commit comments