Тестовое iOS-приложение на UIKit для отображения новостной ленты Autodoc.
UIKitбез storyboard/xibMVVM + Combineдля binding между экраном иViewModelasync/awaitдля всех сетевых запросовUICollectionView + CompositionalLayout + DiffableDataSource- постраничная загрузка новостей (
pageSize = 15) - простой
Clean Architectureбез лишних абстракций - собственный
ImageLoaderнаURLSession + NSCache - адаптивный UI для iPhone и iPad
Проект разделен на слои:
App— точка входа, scene lifecycle, сборка зависимостейCore— networking, image loading, переиспользуемые UI-компоненты и утилитыDomain— сущности, use case, протокол репозиторияData— DTO, endpoint, репозиторий, маппинг API-моделейPresentation— экраны списка и деталей новости
- Открыть AutodocTest.xcodeproj
- Выбрать схему
AutodocTest - Запустить на iPhone или iPad simulator / device с iOS 16.0+
Если нужен regen проекта, достаточно выполнить:
tuist generate --no-open- Список новостей построен на
UICollectionViewDiffableDataSource, обновления выполняются только черезsnapshot. - Пагинация запускается при приближении к хвосту списка и защищена от дублей флагами
isLoadingиcanLoadMore. - Начальное состояние, пустой экран, ошибка и загрузка пагинации отображаются отдельно.
- Экран деталей честно использует доступные поля API и открывает
fullUrlчерезSFSafariViewController.
- первая страница загружается при открытии списка
- следующая страница запрашивается при показе элементов около конца ленты
- новые элементы добавляются без
reloadData - загрузка прекращается, когда:
- загружено
totalCountэлементов - сервер вернул меньше элементов, чем
pageSize
- загружено
Endpointописывает путь и параметры запросаAPIClientработает поверхURLSessionи используетasync/await- есть обработка:
- некорректного URL
- HTTP-ошибок
- decode errors
- transport errors
- timeout настроен на уровне
URLSessionConfiguration
ImageLoaderиспользуетNSCacheдля in-memory cache- повторные запросы одного и того же URL дедуплицируются через
Task-хранилище RemoteImageViewумеет отменять собственную задачу при переиспользовании ячейки- при отсутствии изображения отображается placeholder