使用自定义响应模型
该GraphQLQueryPager
不仅支持返回查询的数据类型,还支持自定义响应类型。自定义响应类型可以是集合或单个对象。这非常有用,当你想要将原始响应转换为用于应用程序消耗的自定义模型时。
转换现有响应类型
类GraphQLQueryPager
遵循Publisher
协议,并提供一个map
方法,允许您将原始响应转换为自定义响应类型。当以这种方式使用时,GraphQLQueryPager
将处理生成Data
类型,但允许每个Data
类型转换为自定义响应类型。这在您想要在多个地方重用单个分页器并向视图模型转换原始数据时特别有用。
在这个例子中,我们取一个返回Result<PaginationOutput<MyQuery.Data, MyQuery.Data>>
的GraphQLQueryPager
,并将原始响应转换为自定义响应类型Result<[Person], Error>
。
// This `GraphQLQueryPager` will return a `Result` of `PaginationOutput<MyQuery.Data, MyQuery.Data>`let initialQuery = MyQuery(first: 10, after: nil)let pager = GraphQLQueryPager(client: client,initialQuery: initialQuery,extractPageInfo: { data inCursorBasedPagination.Forward(hasNext: data.values.pageInfo.hasNextPage ?? false,endCursor: data.values.pageInfo.endCursor)},pageResolver: { page, paginationDirection inswitch paginationDirection {case .next:return MyQuery(first: 10, after: page.endCursor ?? .none)case .previous:return nil}})// Elsewhere in the applicationlet cancellable = pager.map { result inswitch result {case .success((let paginationOutput, let source)):// We may or may not care about the source, but we can use it to transform the response or pass it through as needed.// In this example, we ignore the source and transform the response into a custom response type.let pages = paginationOutput.previousPages + [paginationOutput.initialPage] + paginationOutput.nextPageslet people = pages.flatMap { page indata.values.nodes.map { Person(id: $0.id, name: $0.name) }}return Result<[Person], Error>.success(people)case .failure(let error):return .failure(error)}}.sink { result in// NOTE: This is not guaranteed to run on the main thread. Dispatch to the main thread if necessary.switch result {case .success(let people):// Handle the peoplecase .failure(let error):// Handle the error}}
创建返回自定义响应类型的 GraphQLQueryPager
GraphQLQueryPager类还可以根据自定义类型进行初始化。当以这种方式使用时,GraphQLQueryPager
将在自定义响应类型上操作,而不是在原始Data
类型上。当您想要创建一个返回自定义响应类型的分页器,且不想将原始响应转换成自定义响应类型时,这很有用。
我们为此提供了转换集合类型的一种便捷方法。
在此示例中,我们创建了一个GraphQLQueryPager
,将原始响应转换成自定义响应类型Result<([Person], UpdateSource), Error>
。在此,我们将为每个分页查询的数据调用transform
闭包,并将结果数组连接在一起。
let initialQuery = MyQuery(first: 10, after: nil)let pager = GraphQLQueryPager(client: client,initialQuery: initialQuery,extractPageInfo: { data inCursorBasedPagination.Forward(hasNext: data.values.pageInfo.hasNextPage ?? false,endCursor: data.values.pageInfo.endCursor)},pageResolver: { page, paginationDirection in// As we only want to support forward pagination, we can return `nil` for reverse paginationswitch paginationDirection {case .next:return MyQuery(first: 10, after: page.endCursor ?? .none)case .previous:return nil}},transform: { data indata.values.nodes.compactMap { node inPerson(id: node.id, name: node.name)}})
或者,您也可以返回一个单个模型类型,例如Result<(MyResponseModel, UpdateSource), Error>
。为此,我们使用一个有三个参数的transform
闭包,分别为previousPages, initialPage, nextPages
:
let initialQuery = MyQuery(first: 10, after: nil)let pager = GraphQLQueryPager(client: client,initialQuery: initialQuery,extractPageInfo: { data inCursorBasedPagination.Forward(hasNext: data.values.pageInfo.hasNextPage ?? false,endCursor: data.values.pageInfo.endCursor)},pageResolver: { page, paginationDirection in// As we only want to support forward pagination, we can return `nil` for reverse paginationswitch paginationDirection {case .next:return MyQuery(first: 10, after: page.endCursor ?? .none)case .previous:return nil}},transform: { previousPages, initialPage, nextPages inlet allPages = previousPages + [initialPage] + nextPageslet people = allPages.flatMap { page indata.values.nodes.map { Person(id: $0.id, name: $0.name) }}return MyResponseModel(people: people)})