Архитектура и инструменты
Писать компилирующийся Swift — один навык; структурировать, тестировать и выпускать приложение, которое целая команда сможет менять годами, — другой, и именно его senior-собеседования по iOS проверяют жёстче всего. Senior не просят дать определение optional, но у каждого спрашивают, почему view controller разросся до 1500 строк, где должна жить бизнес-логика и что происходит между зелёной сборкой и телефоном пользователя. Сквозная идея здесь — суждение: редко существует одна верная архитектура или стратегия тестов, есть лишь компромиссы, которые вы можете назвать и защитить.
Тема покрывает три вопроса, определяющих долгосрочное здоровье приложения. Первый — архитектура: паттерны представления (MVC, MVVM, MVP, VIPER, Clean) и обвязка вокруг них (внедрение зависимостей, координаторы, однонаправленный поток), которые удерживают бизнес-логику вне слоя view и делают код тестируемым. Второй — тестирование: пирамида unit-, integration- и UI-тестов, тестовые двойники, изолирующие модуль, и ловушки async и покрытия, из-за которых наборы тестов лгут. Третий — инструменты и релиз: система сборки, менеджеры зависимостей, лабиринт подписи кода и конвейер, превращающий коммит в сборку TestFlight, а затем в версию App Store, которую можно откатить.
Карта темы
- Архитектурные паттерны — MVC и massive view controller, MVVM и биндинги, VIPER и Clean, внедрение зависимостей, координаторы и где живёт бизнес-логика.
- Тестирование — пирамида тестов, XCTest и Swift Testing, mocking через протоколы, тестирование async и снапшотов и почему line coverage — искатель пробелов, а не цель.
- Инструменты и релиз — система сборки Xcode, SPM против CocoaPods против Carthage, подпись кода и provisioning, TestFlight и phased release, CI и символикация крашей.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
| Класть сеть и persistence во view controller | Огромный, нетестируемый контроллер, смешавший четыре обязанности |
| Позволять view model импортировать UIKit или SwiftUI | Presentation-логика становится нетестируемой и связанной с фреймворком |
| Считать «больше покрытия» целью | 85% покрытия, где строки исполняются, но ничего не проверяют, а баги всё равно едут в прод |
Вызывать URLSession.shared прямо внутри тестируемого типа | Нет шва, чтобы подставить fake, поэтому каждый тест ходит в сеть |
| Путать certificate, App ID, entitlement и provisioning profile | Подпись падает на CI с ошибкой, которую в команде никто не может расшифровать |
| Ждать, что automatic signing заработает на чистой машине CI | Сборка падает на отсутствующем profile, который на Mac разработчика был по-тихому |
Значение для собеседований
Это senior-фильтр. Junior пройдёт, дав определение MVVM; от senior ждут, что он выберет MVVM вместо VIPER для команды из 30 инженеров и назовёт компромисс — меньше структуры ради меньшей стоимости входа. Сильнейшие ответы рассматривают архитектуру, тесты и релиз как одну систему: бизнес-логика вынесена в тестируемые типы, пирамида держит быстрых тестов много, а медленных UI-тестов мало, а конвейер способен остановить плохую сборку через kill switch до того, как она дойдёт до большинства пользователей. Цитирование паттернов читается как junior; рассуждение о компромиссе, на который вы сознательно идёте, читается как человек, который выпускал и сопровождал реальные приложения.