Добавьте разбиение на страницы в UIViewController для бесконечной прокрутки с помощью платформы объединения

#ios #swift #pagination #uikit #combine

Вопрос:

Допустим, у меня есть несколько вызовов API, которые извлекают список элементов для данной страницы:

 func getItemsA(_ page: Int) -> AnyPublisher<[A], Never>
func getItemsB(_ page: Int) -> AnyPublisher<[B], Never>
// (and more)
 

Я хочу создать универсальный UIViewController файл с бесконечной прокруткой (страница 1 — 10 элементов, страница 2 — 20 элементов и так далее), Который
(Int)->AnyPublisher<[T], Never> закрывается и выполняет как можно больше внутренней работы (скрытой от внешнего мира).

В настоящее время у меня есть что-то вроде этого (опять же, я упрощаю код, чтобы выделить важные части).

 
// PagedCollectionViewController.swift
class PagedCollectionViewController<T>: UIViewController,
                                        UICollectionViewDelegate {

@Published var items: [T] = []
private var subscriptions = Set<AnyCancellable>()
var getItems: ((Int) -> AnyPublisher<[T], Never>)?

// (...)

    override func viewDidLoad() {
        super.viewDidLoad()
        $items.sink { _ in
            self.collectionView.reloadData()
        }.store(in: amp;subscriptions)

        // get the items on the initial call
        getItems?(currentPage).sink { newItems in
            self.items.append(contentsOf: newItems)
        }.store(in: amp;subscriptions)
    }

// (...)

   func collectionView(_ collectionView: UICollectionView,
                        willDisplay cell: UICollectionViewCell,
                        forItemAt indexPath: IndexPath) {
        let itemsCount = collectionView
            .numberOfItems(inSection: indexPath.section)

       // everytime the user reaches the end of the list we need to load more items
        if indexPath.row == itemsCount - 1 {
           getItems?(currentPage).sink { newItems in
              self.items.append(contentsOf: newItems)
           }.store(in: amp;subscriptions)
        }
    }
}

// HomeViewController.swift
final class HomeViewController: PagedCollectionViewController<A> {

(...)
override func loadView() {
        super.loadView()
        collectionView.dataSource = self
        getItems = interactor?.getItemsA
    }
}

 

Так что меня больше всего интересует та getItems часть PagedCollectionViewController . Я новичок в Объединении, и мне кажется странным, что у меня есть sink метод, вызываемый дважды getItems . Есть ли лучший способ сделать это?

Он PagedCollectionViewController будет использоваться со многими другими контроллерами, и я ожидаю, что он будет работать везде одинаково, поэтому я хочу, чтобы он был как можно более универсальным. У вас есть какие-либо предложения по его улучшению? Может быть, использование Combine именно для этой части (загрузка большего количества элементов) вообще плохая идея? Вы бы решили проблему разбиения на страницы по-другому?

Комментарии:

1. «Я хочу создать универсальный UICollectionViewController» Вопрос!? Где вы пользуетесь UICollectionViewController ?

2. @ElTomato ха, я думал исключительно о поведении контроллера. Так что извините за путаницу, это не было моим намерением, я хочу создать VC, который извлекает страницы при прокрутке вниз с помощью combine и делает его как можно более универсальным и удобным для пользователя