Используйте SwiftUI и Contentful, чтобы быстро создать простое приложение для блога с надежной системой управления контентом.

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

С SwiftUI, как правило, верно обратное - фреймворк позволяет невероятно легко быстро создавать комплексные приложения с нуля или повторять идеи дизайна с помощью кодирования.

Чтобы показать, насколько просто использовать SwiftUI для сложных проектов, я создал приложение для блога с открытым исходным кодом, которое использует систему управления контентом для доставки ваших сообщений и поддерживает многие функции дизайна, такие как темный режим и доступность в стандартной комплектации.

Предпосылки

Чтобы запустить проект, необходимы следующие шаги:

  • Загрузите Xcode 12+.
  • Создайте новый проект SwiftUI.
  • Выберите цель развертывания iOS 14.0 или выше в настройках проекта.

Репозиторий GitHub

Вы можете следить, скачав готовый проект с GitHub.

Настройка Contentful для управления контентом

Первый шаг - настроить вашу модель в системе управления контентом (CMS). Эта модель будет определять, что именно будет опубликовано в приложении после его создания. В нашем случае, поскольку мы создаем приложение для блога, нам нужно создать модель для сообщения в блоге - заголовок, подзаголовок, текст и т. Д.

Для CMS мы будем использовать Contentful, поскольку он имеет большой уровень бесплатного пользования и хорошо интегрируется, в частности, со Swift и SwiftUI.

Первым шагом после создания учетной записи является создание модели контента для нашего сообщения в блоге. Для этого перейдите в Модель контента → Добавить тип контента и выберите имя для модели. Мы будем использовать SwiftBlog с идентификатором API swiftBlog.

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

На этом этапе мы также можем создать пару сообщений, чтобы упростить отладку нашего будущего приложения. Чтобы создать сообщение, вы можете перейти в Content → Add SwiftBlog и создать сообщение с заголовком, подзаголовком, изображением и текстом. Мы можем пока оставить поле Featured пустым и вернуться к нему позже, когда начнем разработку соответствующего раздела нашего приложения.

Создание приложения

После того, как Contentful настроен, пора создать собственное приложение. Прежде чем мы начнем с самого интересного, нам нужно подключить пару необходимых библиотек.

Самое главное, нам нужно добавить Contentful и SDWebImageSwiftUI из диспетчера пакетов Swift. Если вы не знаете, как это делается, перейдите в Файл → Добавить пакеты и найдите два имени выше. В качестве альтернативы используйте эти каталоги GitHub для Contentful и SDWebImageSwiftUI. Об остальном позаботится Xcode, как только вы добавите эти зависимости.

Теперь мы можем начать с самого приложения.

Создание модели данных

Теперь мы переходим к созданию модели данных для нашего сообщения в блоге. Эта модель должна отражать ту же структуру, которую мы создали для нашей модели контента на Contentful, что означает, что у нас будет заголовок, подзаголовок, изображение, фактический текст (сообщение в блоге) и логическое значение для поля Featured. .

Мы устанавливаем для Featured значение по умолчанию false, если мы не укажем иное. Сделав это, мы можем сделать это поле необязательным в нашей модели контента на Contentful и заботиться о нем только тогда, когда мы действительно хотим разместить пост.

Обратите внимание, что мы также заставляем структуруBlogPost соответствовать протоколу Identifiable, добавляя UUID. Это необходимо, потому что мы будем использовать ForEach операторы в наших будущих моделях представления.

Настройка Contentful подключения

Далее мы собираемся создать логику для подключения к нашей CMS. Для этого вам понадобится идентификатор пространства и токен доступа. Вы можете получить их в Настройках → Ключи API на Contentful.

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

try! query.order(by: Ordering(sys: .createdAt, inReverse: true))

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

Еще одно важное замечание: мы передаем наши изображения как URL-адреса, поэтому вначале нам нужно было импортировать библиотеку SDWebImageSwiftUI. Библиотека позволит нам представить изображение с этого URL-адреса с помощью класса WebImage.

Это было для внутренней части нашей интеграции с CMS! Осталось только разработать наше приложение.

Разработка приложения

Для нашего приложения для блога мы собираемся создать два экрана (главный экран с парой избранных постов и список со всеми постами) и всего три компонента (открытка блога для главного экрана, строка поста блога для списка, и фактическое представление сообщения в блоге).

Создание дизайна карточки для главного экрана

Создавать карты в SwiftUI довольно просто, используя все стандартные компоненты, такие как вертикальные и горизонтальные стопки и тексты. Единственная небольшая сложность здесь - это представление веб-изображений из нашей CMS, которые, как упоминалось ранее, мы решаем с помощью библиотеки SDWebImageSwiftUI.

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

Теперь о самой карте. Здесь мы собираемся заняться двумя важными вещами.

Во-первых, мы собираемся сделать карту максимально адаптируемой к размеру экрана, минимизируя жестко заданные значения для размера карты. Этого обычно легко достичь в SwiftUI, не делая ничего лишнего (все VStack и HStack представления автоматически адаптируются к размеру экрана), но когда дело доходит до изображений, мы хотим убедиться, что они хорошо смотрятся на экране любого размера. Вот почему мы собираемся исправить высоту изображения до 220 пикселей, используя следующий код для установки ширины:

.frame(maxWidth: UIScreen.main.bounds.width — 80)

Это означает, что мы определяем фактический размер экрана устройства, на котором будет открыто приложение, беря ширину экрана и делая наше изображение на 80 пикселей меньше, чем какой бы размер ни был. Как всегда в SwiftUI, это не единственный способ добиться адаптируемости, но для нашей конкретной карты этот метод будет работать лучше всего.

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

Существует несколько способов реализовать цветовую схему для темного режима, но поскольку нам нужен только один настраиваемый цвет в нашем приложении для карты, мы просто будем использовать фактическое шестнадцатеричное значение темно-серого цвета, если значение @Environment(\.colorScheme) var colorScheme равно .dark:

.background(colorScheme == .dark ? Color(hex: “#121212”) : Color.white)

Вот полный код нашей основной открытки в блоге:

А вот результат для iPhone 12 и iPhone 8. Обратите внимание, что карта автоматически адаптируется к размеру экрана и режиму внешнего вида, и оба выглядят довольно хорошо.

Разработка строки списка

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

Вот последний код, который мы используем для строки списка с каждым сообщением в блоге:

И вот результат того, как будет выглядеть каждая строка.

Создание подробного представления сообщения в блоге

Следующим шагом является разработка того, как наши сообщения в блоге будут выглядеть, когда мы их откроем. Здесь мы снова не делаем ничего экстраординарного: мы просто разместим изображение, заголовок и текст в вертикальном стеке и обернем его ScrollView. Как обычно, SwiftUI позаботится о доступности и темном режиме.

На изображении ниже вы можете увидеть, как наши сообщения будут выглядеть внутри, когда мы их откроем.

Создание финальных экранов

Теперь, когда мы создали наши основные компоненты, мы можем просто расположить их на последних экранах так, как мы хотим. В нашем приложении у нас будет всего две вкладки - Главная с парой избранных и последних статей и Просмотреть все, где у нас будет список всех сообщений в блоге. .

Последнее может легко служить яркой демонстрацией простоты SwiftUI. Поскольку у нас уже есть хранилище наших сообщений в блогах и компонент для их отображения в списке, остается только создать NavigationView с List, отображая сообщения в блоге с помощью оператора ForEach. Обратите внимание, что нам не нужно выполнять дополнительную работу, чтобы адаптировать список к размеру экрана или режиму внешнего вида - SwiftUI делает все, что скрыто под капотом.

Теперь к главному экрану. Главный экран будет состоять из двух частей - раздела для избранных сообщений и раздела для последних сообщений. Последнее довольно просто и не заслуживает особого внимания - мы просто используем горизонтальный ScrollView с карточками, которые мы сделали ранее, и ограничиваем количество сообщений в операторе ForEach до нужного нам числа. Вы можете найти полный код этого представления в репо здесь.

Что касается избранных сообщений, здесь мы, наконец, будем использовать наше логическое поле Featured, которое мы добавили в нашу модель контента в Contentful. Чтобы получить только избранные сообщения, мы можем использовать вычисляемое свойство, в котором мы фильтруем все сообщения, чтобы возвращать только те, для которых в поле Featured установлено значение true.

Расположение экранов с помощью TabView

Последний шаг - расположить наши два экрана в файле ContentView с TabView и создать объект @StateObject для хранилища сообщений блога, который будет использоваться во всех дочерних представлениях.

Вот и все, теперь наше приложение готово к использованию!

Заключение

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

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

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

Спасибо за прочтение!