From cefeafb03ff4c1277d6bb4cbdb81748ad1cc46db Mon Sep 17 00:00:00 2001 From: Hesham Salman Date: Wed, 24 Jul 2024 14:58:45 -0400 Subject: [PATCH] Bring the inits --- .../AsyncGraphQLQueryPager.swift | 52 ++++++++++++++++++- .../ApolloPagination/GraphQLQueryPager.swift | 47 +++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/apollo-ios-pagination/Sources/ApolloPagination/AsyncGraphQLQueryPager.swift b/apollo-ios-pagination/Sources/ApolloPagination/AsyncGraphQLQueryPager.swift index 31226545d..0a249c147 100644 --- a/apollo-ios-pagination/Sources/ApolloPagination/AsyncGraphQLQueryPager.swift +++ b/apollo-ios-pagination/Sources/ApolloPagination/AsyncGraphQLQueryPager.swift @@ -15,6 +15,34 @@ public class AsyncGraphQLQueryPager: Publisher { public var canLoadNext: Bool { get async { await pager.canLoadNext } } public var canLoadPrevious: Bool { get async { await pager.canLoadPrevious } } + init, InitialQuery, PaginatedQuery>( + pager: Pager, + transform: @escaping (PaginationOutput) throws -> Model + ) { + self.pager = pager + Task { + let cancellable = await pager.subscribe { [weak self] result in + guard let self else { return } + let returnValue: Output + + switch result { + case let .success(output): + do { + let transformedModels = try transform(output) + returnValue = .success(transformedModels) + } catch { + returnValue = .failure(error) + } + case let .failure(error): + returnValue = .failure(error) + } + + _subject.send(returnValue) + } + _ = $cancellables.mutate { $0.insert(cancellable) } + } + } + init, InitialQuery, PaginatedQuery>( pager: Pager ) where Model == PaginationOutput { @@ -55,9 +83,29 @@ public class AsyncGraphQLQueryPager: Publisher { extractPageInfo: extractPageInfo, pageResolver: pageResolver ) - self.init( - pager: pager + self.init(pager: pager) + } + + public convenience init< + P: PaginationInfo, + InitialQuery: GraphQLQuery, + PaginatedQuery: GraphQLQuery + >( + client: any ApolloClientProtocol, + initialQuery: InitialQuery, + watcherDispatchQueue: DispatchQueue = .main, + extractPageInfo: @escaping (PageExtractionData) -> P, + pageResolver: ((P, PaginationDirection) -> PaginatedQuery?)?, + transform: @escaping (PaginationOutput) throws -> Model + ) where Model == PaginationOutput { + let pager = AsyncGraphQLQueryPagerCoordinator( + client: client, + initialQuery: initialQuery, + watcherDispatchQueue: watcherDispatchQueue, + extractPageInfo: extractPageInfo, + pageResolver: pageResolver ) + self.init(pager: pager, transform: transform) } /// Subscribe to the results of the pager, with the management of the subscriber being stored internally to the `AnyGraphQLQueryPager`. diff --git a/apollo-ios-pagination/Sources/ApolloPagination/GraphQLQueryPager.swift b/apollo-ios-pagination/Sources/ApolloPagination/GraphQLQueryPager.swift index 38942a2a4..d715346a6 100644 --- a/apollo-ios-pagination/Sources/ApolloPagination/GraphQLQueryPager.swift +++ b/apollo-ios-pagination/Sources/ApolloPagination/GraphQLQueryPager.swift @@ -15,6 +15,31 @@ public class GraphQLQueryPager: Publisher { public var canLoadNext: Bool { pager.canLoadNext } public var canLoadPrevious: Bool { pager.canLoadPrevious } + init, InitialQuery, PaginatedQuery>( + pager: Pager, + transform: @escaping (PaginationOutput) throws -> Model + ) { + self.pager = pager + pager.subscribe { [weak self] result in + guard let self else { return } + let returnValue: Output + + switch result { + case let .success(output): + do { + let transformedModels = try transform(output) + returnValue = .success(transformedModels) + } catch { + returnValue = .failure(error) + } + case let .failure(error): + returnValue = .failure(error) + } + + _subject.send(returnValue) + } + } + init, InitialQuery, PaginatedQuery>( pager: Pager ) where Model == PaginationOutput { @@ -46,6 +71,28 @@ public class GraphQLQueryPager: Publisher { self.init(pager: pager) } + public convenience init< + P: PaginationInfo, + InitialQuery: GraphQLQuery, + PaginatedQuery: GraphQLQuery + >( + client: any ApolloClientProtocol, + watcherDispatchQueue: DispatchQueue = .main, + initialQuery: InitialQuery, + extractPageInfo: @escaping (PageExtractionData) -> P, + pageResolver: ((P, PaginationDirection) -> PaginatedQuery?)?, + transform: @escaping (PaginationOutput) throws -> Model + ) where Model == PaginationOutput { + let pager = GraphQLQueryPagerCoordinator( + client: client, + initialQuery: initialQuery, + watcherDispatchQueue: watcherDispatchQueue, + extractPageInfo: extractPageInfo, + pageResolver: pageResolver + ) + self.init(pager: pager, transform: transform) + } + deinit { pager.reset() }