Доклад: SwiftUI Inside / Александр Скворцов (Яндекс)
Введение в SwiftUI
Приветствие и представление докладчиков
- Всем привет, рад вас видеть на вечерней сессии сезона Подлодка Crew, посвящённой Swift.
- Доклад проведут Евгений Ануфрейчик и Никита Краснов, а расскажет о SwiftUI Саша Скворцов из Яндекса.
Цели и структура доклада
- Саша упоминает, что будет обсуждаться малоизвестная информация о SwiftUI, которая отсутствует в документации.
- Доклад разделен на несколько логических частей с перерывами для вопросов после каждой части.
Проблемы разработки на SwiftUI
Начало работы с приложением
- Разработка началась в 2023 году с использованием чистого SwiftUI на iOS 15 Plus. Ожидали красивую реализацию от Apple.
- В процессе разработки столкнулись с багами как по своей вине, так и из-за проблем в самом инструменте. Несмотря на это, разработка ускорилась благодаря SwiftUI.
Локальные мемы и проблемы
- Появился локальный мем о том, как менеджеры приносят скриншоты багов со словами "это же просто Swift UI".
Анимации в SwiftUI
Пример кода с анимацией
- Рассмотрен простой код с красным кружочком внутри синего: если флажок true — показываем красный кружочек; если false — только синий.
Отличия от Core Animation
- В отличие от Core Animation, анимации в SwiftUI могут быть рваными из-за того, что они работают в одном процессе и потоке. Это приводит к большему количеству багов при управлении главной нитью приложения.
Навигация в приложениях на SwiftUI
Проблемы стандартного Navigation View
- Стандартный Navigation View имеет плавающие баги: кнопки не реагируют на действия даже при правильном отображении жестов и хайлайтов.
Ограничения API навигации
- API Navigation View ограничен: нет возможности сделать кастомные переходы между экранами без использования более новых технологий (iOS 16+).
Хранение состояния в навигации
- При использовании state или state object состояние может сбрасываться при скрытии/показе элементов интерфейса, что создает дополнительные сложности для разработчиков.
Обсуждение состояния вьюх и навигации
Состояние вьюх при использовании хостинг-контроллера
- При оборачивании вьюхи в хостинг-контроллер, состояние сохраняется даже при скрытии и показе элемента. Это позволяет пользователю скроллить и взаимодействовать с интерфейсом без потери данных.
Важность методов onAppear и onDisappear
- Если скрывать вьюху через opacity, методы onAppear и onDisappear не будут работать, что может негативно сказаться на бизнес-логике приложения. Например, это важно для загрузки изображений при входе на экран.
Проблемы кастомной навигации
- Реализация кастомной навигации на примитивах SwiftUI затруднена из-за отсутствия возможности сохранить состояние вьюхи без использования хостинг-контроллера.
Работа Navigation View
- Navigation View работает корректно благодаря тому, что Navigation Link оборачивает контент в хостинг-контроллер. Это позволяет сохранять состояние при переходах назад.
Вопросы о реализации компонентов
- Участники обсуждают детали реализации UI hosting controller и его отсутствие в коде Navigation Link. Также поднимается вопрос о том, как правильно использовать эти компоненты вместе.
Анимация и её реализация
Проблемы с анимацией
- Участники обсуждают ограничения использования Navigation Link внутри Navigation Stack. Это приводит к необходимости использовать модификатор Navigation Destination для правильной работы.
Технические аспекты анимаций
- Обсуждается использование Metal для анимаций под капотом SwiftUI. Упоминаются проблемы с производительностью и необходимость GPU для сложных эффектов.
Проблемы Scroll View
Ограничения стандартного Scroll View
- Стандартный Scroll View имеет недостатки, такие как отсутствие прямого контроля за контентом. Базовые функции остаются недоступными или требуют обходных путей.
Использование текстовых описаний фреймворков
- Начиная с появления стабильного ABI в Swift, модули генерируют текстовые описания, которые могут быть использованы для улучшения функциональности Scroll View.
Поиск альтернативных решений
- Участники обсуждают возможность использования текстовых описаний для доступа к дополнительным функциям Scroll View, которые не документированы официально.
Обсуждение проблем с ленивыми контейнерами
Проблемы с ленивостью в ScrollView
- В репе почти все содержимое связано с проблемами ленивости в контейнерах, что делает их бесполезными для длинного контента.
- Обсуждение вопросов по теме лучше оставить на потом, чтобы сосредоточиться на докладе.
Глубокое понимание технологий
- Документация полезна, но недостаточна для решения сложных ситуаций, которые не описаны в гайдах.
- Часто код работает иначе, чем ожидалось из-за недостатка информации о технологиях.
Структура и внутренние механизмы Swift UI
Понимание C++ внутри Swift UI
- Swift UI имеет элементы C++, что можно увидеть через брекпоинты и символы.
- AG (атрибут графа) — это приватный фреймворк, доступный для реверс-инжиниринга.
Работа с объектами и символами
- Команда NM позволяет просмотреть символы объектного файла; опция C demanglit улучшает читаемость плюсовых символов.
- Внутренние структуры могут ссылаться на сущности из атрибут графа.
Методы и протоколы в Swift UI
Протокол View и его методы
- Протокол View включает не только метод Body, но также три дополнительных метода: make view, make view list и view list count.
- Реализация этих методов приводит к их вызову вместо стандартного метода View.
Связь между методами и графом
- Если реализован один из приватных методов, он будет вызываться вместо стандартного метода Body.
Работа со состоянием в Swift UI
Dynamic Property и его реализация
- State реализует протокол Dynamic Property; важно изучить его интерфейс для понимания работы состояния.
Процесс добавления Views в граф
- При добавлении View создается приватный объект граu с начальными значениями свойств.
- Swift UI использует память для хранения состояния View; изменения сохраняются благодаря динамическому управлению свойствами.
Понимание состояния в Swift UI
Использование state из view
- Обсуждается, почему состояние (state) можно использовать только из представления (view). Изменения в конструкторе view не влияют на состояние.
Дебаггинг и память
- В процессе дебага проверяется соответствие значений в памяти с заданными начальными значениями. Убедились, что указатель на объект совпадает с ожидаемым.
Оптимизация и наблюдение
- Обсуждается флажок red, который может быть использован для оптимизации при изменении состояния. Это влияет только на те компоненты, которые зависят от него.
Применение знаний на практике
- Рассматривается пример кода, где sibling получает значение состояния извне. Подчеркивается, что изменения не повлияют на sibling после первого вычисления.
Вопросы и обсуждения
- Задаются вопросы о приватных API в Swift UI. Уточняется, что многие скрытые API могут использоваться без ограничений.
Приватные API и их использование
Скрытые API в Swift UI
- Объясняется природа приватных API: они не совсем приватные, а скорее скрытые. Их использование возможно благодаря тому, что компилятор позволяет инлайнить функции.
Проект по бэкпортированию функций
- Упоминается проект по бэкпортированию функций с более новых версий Swift на старые версии с использованием скрытых API.
Атрибьют граф и его роль
Что такое атрибьют граф?
- Атрибьют граф представляет собой структуру состояния Swift UI. Он определяет, какие элементы нужно перерисовать при изменении состояния и как рассчитывать макеты.
Жизненный цикл стейта
- Стейт живет в атрибьют графе; он должен быть правильно связан для функционирования. Если состояние не связано с атрибьют графом, оно будет "полумертвым".
Влияние изменений на стейт
- Изменения в состоянии внутри конструктора view не будут иметь эффекта вне этого контекста; это подчеркивает важность правильного связывания состояний между компонентами.
Обсуждение Nonmutating Set и его применение
Понимание Nonmutating Set
- Nonmutating set позволяет записывать значения в структуру, даже если она не изменяется. Это важно для управления состоянием.
- Структура состояния (state) начинает понимать, куда писать данные только после вызова метода make property.
Атрибутный граф
- Значения записываются в атрибутный граф, когда оба поля состояния заполнены. Это позволяет косвенно взаимодействовать с графом.
- Сериализация данных используется для передачи информации между процессами и устройствами, что делает её важной частью разработки.
Сериализация и работа с JSON
Применение сериализации
- Существует множество форматов сериализации, включая JSON. Это необходимо для работы с виджетами и их интерактивностью.
- Интерактивность в виджетах реализуется через URL и интенты из-за ограничений на использование замыканий.
Структура сериализованных данных
- Сериализованная верстка представлена массивом узлов (nodes), где каждый узел имеет свойства (properties), идентификаторы и атрибуты.
- Даже простая вьюха может генерировать сложные структуры JSON, содержащие более 900 строк кода.
Вопросы о состоянии и применении знаний
Обсуждение вопросов
- Вопрос о том, как состояние влияет на работу виджетов. Участники обсуждают возможность применения знаний из доклада на практике.
- Знания о внутреннем устройстве технологий помогают лучше понимать их использование и создавать лучшие практики.
Выводы по использованию технологий
- Swift QI не является заменой UIKit; это высокоуровневый интерфейс программирования (API).
- Исследование базовых инструментов доступно без дополнительных затрат; важно обогащать свои знания.
Заключительные мысли и вопросы
Завершение доклада
- Доклад завершился обсуждением проблем с состоянием приложений и возможностями Swift QI.
- Участники могут задавать вопросы после доклада для дальнейшего обсуждения тематики.
Ответы на популярные вопросы
- Один из популярных вопросов касался анимации кружков: предложено использовать альтернативные методы вместо исправления существующих проблем.
Сложные случаи и использование Swift
Вопросы о менеджерах и их знаниях
- Обсуждение о том, что менеджеры, похоже, не изучают ничего кроме разработки на Swift. Это вызывает вопросы о глубине их знаний.
- Упоминается шутливый вопрос о том, какие еще слова выучили менеджеры помимо терминов из Swift.
Использование Scroll View и List
- Говорится о том, что автор не изучал использование List в Swift, но предполагает, что он использует Table View внутри.
- Подчеркивается важность исследования новых технологий и дележа полученными знаниями с коллегами для улучшения приложений.
Кастомизация навигации в приложениях
Создание кастомной обертки
- Обсуждается создание кастомной обертки на Navigation контроллерах для улучшения навигации в приложении.
- Упоминается проблема с Back Action в кастомной обертке и то, как она решается при наличии Navigation контроллера.
Проблемы с багами
- Отмечается отсутствие багов после перехода на кастомную обертку по сравнению с предыдущими версиями приложения.
Работа с API и интеграция UI Kit
Взаимодействие между UI Kit и SwiftUI
- Задается вопрос о том, как работает UI Kit внутри SwiftUI. Автор подчеркивает необходимость уточнения вопросов для более глубокого понимания.
- Описывается опыт использования вставок из UIKit для решения задач анимации в SwiftUI.
Рекомендации по использованию API
- Предостережение против неправильного использования API при создании экземпляров UIView. Это может привести к багам из-за дублирования экземпляров.
- Подчеркивается важность создания новых экземпляров UIView каждый раз для предотвращения проблем с отображением.