Как стать автором
Обновить

Лучшие практики и инструменты при разработке iOS приложений

Время на прочтение 7 мин
Количество просмотров 8.5K
Автор оригинала: Piotr Gorzelany
Разрабатывая мобильные приложения, мне не раз приходилось создавать проекты с нуля. При этом я и моя команда всегда тратили много времени на основную настройку проекта, такие как интеграция сторонних инструментов, настройка структуры проекта, написание базовых классов, интеграция внешних библиотек и т.д.

Я решил, что время, затрачиваемое на запуск проекта, можно уменьшить, а основную часть процесса можно автоматизировать. При этом я собрал лучшие практики и инструменты, которые мы использовали, и подготовил шаблон проекта, который мы используем при запуске новых проектов. Такой шаблон должен сэкономить время разработчика на конфигурацию нового проекта, а также обеспечить общую структуру проекта, к которой привыкнет каждый член команды, чтобы больше не приходилось думать и изучать структуру нового для него проекта. Теперь это всегда одинаково.

Каждый инструмент или подход, добавленный в шаблон, заслуживают отдельной статьи, но я хотел бы попытаться суммировать каждый пункт и дать краткое объяснение того, почему я включил их в данную статью.

Cocoapods


Я не думаю, что Cocoapods требует представления. Это библиотека для управления внешними зависимостями для IOS проектов. Она существует уже давно и является надежной и проверенной на практике в тысячах (если не в миллионах) проектов. Также существуют и альтернативные менеджеры зависимостей, например: Carthage, но я решил продолжить с Cocoapods, потому что у нее самый широкий спектр поддерживаемых проектов с открытым исходным кодом. Использовать Cocoapods очень просто, и он предоставляется с search index, который позволяет легко находить пакеты, которые могут пригодиться в любой момент.

Проект шаблона предоставлен с простым Podfile, который содержит Swiftlint и R.swift. Шаблон также включает Gemfile для управления версией Cocoapods, используемой для управления зависимостями. Данное решение является часто игнорируемым разработчиками, но оно предотвращает проблемы, возникающие, когда разработчики Вашей команды устанавливают зависимости, используя различные версии Cocoapods. Gemfile принудительно использует одну и ту же версию Cocoapods для всей команды.

Swiftlint


Swiftlint — это очень полезный инструмент для обеспечения соблюдения определенных правил и стиля написания кода каждым разработчиком в одной команде. Данную систему можно было бы рассматривать, как автоматизированную систему проверки кода, которая предупреждает разработчика об опасных моментах, таких, как, например, force casts, force tries и т. д., но кроме вышесказанного, данная система применяет общий стиль написания кода, следя за тем, чтобы все разработчики следовали одинаковым правилам, связанным со «стилем кода», например: отступы или интервалы. Такой подход имеет огромные преимущества, не только выполняя экономию времени на проверку кода, но также делает файлы проекта узнаваемыми, что повышает их читабельность и, как следствие, их понимание всеми участниками команды разработчиков. По данной ссылке предоставлен список всех правил. В шаблоне, Swiftlint он устанавливается посредством Cocoapods и включается в шаг «Фазы компиляции», поэтому он покажет предупреждение разработчику при каждой компиляции проекта.

R.swift


R.swift — это инструмент для получения строго типизированных, автоматически заполненных ресурсов, таких как изображения, сегменты шрифты и локализации. Он выполняет все перечисленные действия путем сканирования проекта и создания классов, необходимых для получения ресурсов. Самым большим преимуществом этой библиотеки является то, что при использовании ресурсов она делает программный код:

  • Fully typed — меньше приведений и предположений о том, какой метод будет возвращен
  • Compile time checked — больше не существует не корректных строк, которые приводят к остановке работы приложения во время выполнения кода
  • Autocompleted — отсутствие необходимости угадывать заново название image/nib/storyboard

Рассмотрим следующий код с использованием официального строкового API:

let icon = UIImage(named: “custom-icon”)

Если вы ошиблись в названии изображения, вы получите ноль. Если какой-либо член вашей команды изменит имя ресурса изображения, этот код вернет ноль или его выполнение будет остановлено, если вы принудительно развернете изображение. При использовании R.swift это выглядит так:

let icon = R.image.customIcon()

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

R.swift устанавливается посредством Cocoapods и интегрируется в шаблон в Фазе компиляции и будет генерировать классы оболочки Swift для каждой компиляции. Это означает, что если вы добавите файл / изображение / локализацию / шрифт / цвет / перо и т. д., то все это будет доступно посредством R.swift после компиляции проекта.

Отдельный файл AppDelegate для тестов


Очень часто забывают о хорошей практике использования отдельного класса TestAppDelegate при запуске тестов. Почему это хорошая идея? Обычно класс AppDelegate выполняет много работы при запуске приложения. Он может иметь логику конфигураций window, конфигурировать базовое отображение пользовательского интерфейса приложения, выполнить логику регистрации для получения уведомлений, иметь код настройки подключения к базе данных и даже иногда выполнять вызовы серверного API. Юнит тесты не должны иметь сайд эффектов. Вы действительно не хотите выполнять вызовы случайных API и настраивать всю структуру пользовательского интерфейса вашего приложения только для запуска юнит тестов?

TestAppDelegate также является подходящим выбором для того, чтобы получить код, который вы хотите запускать только один раз во время выполнения набора тестов. Он может содержать код, который генерирует мок-объекты, заглушки сетевых запросов и т. д.

Шаблон содержит файл main.swift, который является основной точкой входа для приложения. В этом файле есть методы, которые проверяют среду работы приложения, и, если это тестовая среда, они вызывают TestAppDelegate.

Флаги профилирования производительности компилятора


Swift — это отличный язык, более простой в использовании и более безопасный, чем Objective-C (IMO). Но когда он был впервые представлен, у него был один большой недостаток — время компиляции. Вернувшись в дни, когда я работал над проектом в Swift, в котором было примерно 40 тыс. строк кода Swift (проект среднего размера). Код был очень тяжелым, с параметрами настройки и выводом типов, а компиляция чистой сборки заняла почти 5 минут. При внесении даже небольших изменений, проект повторно компилируется и это занимает около 2 минут, чтобы увидеть изменения. Это было одним из худших событий, которые я когда-либо испытывал, и из-за этого я почти прекратил использовать Swift.

Тогда единственным решением было попытаться профилировать время компиляции проекта и изменить свой код таким образом, чтобы компилятор работал быстрее. В помощь решения таких проблем, Apple вводит некоторые неофициальные флаги компилятора, которые предупреждают разработчика, о том, что компиляция тела метода или определение типа выражения занимает слишком много времени. Я добавил эти флаги в проект шаблона, для предупреждения о длительном времени компиляции вашего приложения.

В наши дни, время компиляции значительно уменьшилось, и разработчикам очень редко приходится оптимизировать свой код только для того, чтобы уменьшить время компиляции. Но все же лучше обо всем знать заранее, чем пытаться решить данную проблему, когда проект становится слишком большим.

Dev/Staging/Production configurations


Еще один хороший подход (или, можно сказать, необходимость) — иметь отдельную конфигурацию и переменные среды для сред разработки, финального тестирования и публикаций приложения. В настоящее время почти каждое приложение должно работать с сервером, и обычно такие сервера развертываются в нескольких средах. Среда разработки используется для ежедневного развертывания разработчиками для тестирования своего кода. Среда финального тестирования используется для создания стабильных релизов или для тестирования тестировщиками и клиентами.

Одним из способов поддержки нескольких сред в проекте iOS является добавление конфигураций на уровне проекта.

image
Конфигурации уровня проекта

Определив конфигурации, можно создать файл Configuration.plist, содержащий переменные для каждой среды.

image
Configuration.plist

При запуске проекта имеется возможность указывать, какую конфигурацию следует использовать. Вы можете сделать это в схеме сборки.

image

Затем необходимо добавить еще одно свойство в файл проекта Info.plist. Значение данного свойства будет динамически подставляться во время выполнения в имя текущей конфигурации.

image
Все это предварительно настроено в шаблоне.

Осталось только написать класс, который может извлекать эти переменные во время выполнения в зависимости от конфигурации, выбранной в схеме сборки. Шаблон содержит класс ConfigurationManager, который может извлекать переменные для текущей среды. Также можно проверить реализацию данного класса на Github, чтобы увидеть, как он работает.

Readme


Каждый проект должен содержать файл Readme, в котором, по крайней мере, содержатся инструкции по установке зависимостей и запуску проекта. Он также должен содержать описания архитектуры проекта и модулей. К сожалению, разработчики не любят писать документацию (файл readme является частью этой работы), и я видел проект, который разрабатывался месяцами, и у него даже был файл Readme. Чтобы снять бремя написания файла readme, шаблон содержит стандартный файл readme, который охватывает установку и структуру проекта. При настройке нового проекта с использованием шаблонов, вы автоматически включаете файл Readme.

Gitignore


В настоящее время большинство проектов используют GIT в качестве системы контроля версий. При использовании GIT у разработчиков нет желания игнорировать некоторые файлы или папки в проекте, например папку сборки или папку производных данных. Чтобы избавить разработчика от необходимости поиска файла gitignore, подходящего для его проекта iOS, шаблон содержит стандартный gitignore, предоставленный участниками Github.

Базовые классы для обработки внешних ссылок и уведомлений


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

Вывод


Подводя итог, описанный шаблон содержит наилучшие подходы и интегрирует полезные инструменты сторонних разработчиков. Все это должно сэкономить Вашей команде время разработки, потраченные на настройку нового проекта, а также обеспечить общую и прочную основу для остальной части проекта. Пусть данный шаблон послужит Вам и Вашей команде на пользу!
Теги:
Хабы:
+7
Комментарии 14
Комментарии Комментарии 14

Публикации

Истории

Работа

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн