Давайте создадим ленту Hacker News API с бесконечной прокруткой
Введение Combine, среды реактивного программирования Apple, сделало URLSession
и несколько других типов Foundation намного более мощными.
URLSession
буквально на стероидах, а его издатель (dataTaskPublisher
) позволяет нам делать много вещей. В частности, операторы Combine позволяют нам легко декодировать, повторять попытки, обрабатывать ошибки и связывать несколько запросов, среди прочего.
Наша цель
Цель этой статьи - создать список бесконечной прокрутки SwiftUI. Для этого мы будем использовать Combine и URLSession
в Hacker News API в нашем приложении для iOS.
Если фреймворк Combine для вас новичок, я бы порекомендовал вам просмотреть Глубокое погружение в фреймворк Combine в Swift, прежде чем продолжить.
К концу этой части вы сможете добиться следующего результата:
Начиная
Чтобы настроить список SwiftUI, отображающий данные из веб-API, нам нужно настроить класс ObservableObject
, как показано ниже:
Оператор карты преобразует результат API в нового издателя, который возвращает data
из ответа API.
Важно установить receive(on:)
для основного потока для обновления списка и store
подписку в отменяемом экземпляре, чтобы поддерживать его в действии.
Мы будем использовать эти данные на следующем этапе для декодирования JSON с использованием протокола Codable
, как показано ниже:
Структура HNItem
должна соответствовать протоколу Identifiable
для списка SwiftUI, чтобы отличать каждую строку от других.
Результаты API устанавливаются в свойстве hnItems
класса HackerNewsFeed
. Поскольку у него есть оболочка свойства Published, изменения отражаются в списке SwiftUI, как показано ниже:
Впоследствии в нашем симуляторе мы получаем следующий результат:
Таким образом, мы добавили URLSession
результатов в список SwiftUI. Но список еще нельзя прокручивать бесконечно. Давай настроим это.
SwiftUI List Endless Scroll
В настоящее время SwiftUI не предоставляет встроенной поддержки для прослушивателя прокрутки. К счастью, для этого есть обходной путь.
Чтобы настроить бесконечную прокрутку в списке SwiftUI, нам нужно обработать следующие сценарии в нашем коде:
- Используя метод
onAppear
в строках списка, мы можем определить, когда пользователь достиг последнего элемента, и соответственно вызвать запрос API для следующей страницы. - Чтобы предотвратить дублирование запросов API и обеспечить синхронизацию сетевых запросов, мы будем использовать перечисление для отслеживания состояния.
Кроме того, мы можем настроить другое перечисление для обработки ошибок.
Обновленный код для класса HackerNewsFeed
, расширяющего ObservableObject
, приведен ниже:
Мы изменили несколько вещей в функции fetchStories
в приведенном выше коде:
- Пока запрос не вернет результат, перечисление
pageStatus
настроено на загрузку. tryMap
используется вместо оператораmap
для обработки сетевых ошибок.tryFilter
используется для обработки пользовательских ошибок. В нашем случае свойствоexhaustiveNbHits
возвращается какfalse
при достижении лимита запросов API. Итак, мы выдаем соответствующую ошибку, которая вызывает сбой вsink
.endOfList
- это новое опубликованное свойство, используемое для вызова диалогового окна с предупреждением об определенных ошибках.
Функция shouldLoadMore
решает, когда запускать следующий запрос API во время пользовательской прокрутки. Он вызывается во время onAppear
в строках списка, как показано ниже:
В результате мы получим результат, как показано ранее.
API-интерфейс Hacker News, который мы использовали в приложении, имеет ограничение в 1000 результатов. Достигнув конца прокрутки, мы получим диалоговое окно с предупреждением, как показано ниже:
Заключение
Мы смогли создать приложение Hacker News Stories с бесконечной прокруткой ленты новостей с помощью SwiftUI и Combine.
В дальнейшем вы можете использовать оператор replaceError
или catch
для обработки проблем синтаксического анализа в JSON и настройки издателя восстановления.
Кроме того, вы можете точно настроить функцию shouldLoadMore
для загрузки следующего пакета результатов до того, как пользователь дойдет до последнего элемента (может быть, инициировать запрос, когда он находится на третьем с последнего элемента?).
Код вышеуказанного iOS-приложения SwiftUI доступен в репозитории Github.
На этом все - спасибо за чтение.