Ниже представлен начальный фрагмент Лекции 3 Стэнфордского курса CS193P Весна 2023 «Разработка iOS приложений с помощью SwiftUI«.
Полный русскоязычный неавторизованный конспект Лекции 3 в формате Google Doc и в виде PDF-файла, который можно скачать и использовать offline, доступны здесь.
Код находится на GitHub.
С полным перечнем Лекций и Домашних Заданий на русском языке можно познакомиться здесь.
В этой Лекции вы увидите, наверное, самое большое количество слайдов на протяжении всего семестра, но нам нужно изучить базовую архитектуру прежде, чем погрузиться в следующую часть демонстрационного приложения, которая будет освещаться во второй половине сегодняшней Лекции.
Есть вопросы, прежде чем я начну? Хорошо, нет.
Итак, Лекция номер 3.
У нас есть две очень большие темы для разговора: одна из них — MVVM, которая представляет собой архитектуру, парадигму дизайна, которую вы будете использовать для создания iOS приложений, вторая — система ТИПов Swift:
Сегодня
MVVM
- Парадигма конструирования
Система ТИПов Swift
- struct — структура
- class — класс
- protocol — протокол
- “Don’t Care” ТИП (Generic) — “Не важно какой” ТИП (Дженерик)
- enum — перечисления
- functions — функции
Возвращаемся к Демо!
- Применение MVVM к Memorize
В Swift
есть разные ТИПы: структура struct, протокол protocol и многое другое.
Итак, это две основные темы Лекции 3, а затем я вернусь к демонстрационному приложению, в которой мы начнем создавать логику игру Memorize, то есть что происходит, когда вы кликаете на карты.
Архитектура MVVM
Итак, что это за штука MVVM?
Надо сказать, что в Swift
очень важно отделить логику и данные вашего приложения от пользовательского интерфейса (UI
).
Это действительно очень важно.В некотором смысле, SwiftUI
построен на той идее, что у вас будут ДАHHЫЕ и ЛОГИКА, которые связаны с тем, что делает ваше приложение, и еще у вас будет UI
, который покажет это пользователю и будет взаимодействовать с пользователем как совершенно отдельная вещь. Так что это реально очень важно.
Та часть приложения, которая связана с ДАННЫМИ и ЛОГИКОЙ, например, в нашем приложении Memorize это “что происходит, когда вы кликаете на карте?” или “карты лежат лицом вверх или лицом вниз?”, все это, мы называем Model (Моделью) нашего приложения. Вы услышите, что я использую это слово Model (Модель) сотни раз. Вся логика и данные “живут” в Model (Модели).
Всё, что мы делали до сих пор на этом курсе, был только UI
и иногда мы будем называть его View, потому что это наш «взгляд», наш портал на Model (Модель).
Model и UI
Отделение «Логика и данных» от UI
SwiftUI
очень серьезно относится к отделению логики и данных приложения отUI
- Мы называем логику и данные нашей Model (Моделью)
- Это может быть структура struct или
SQL
база данных или некоторый код машинного обучения или многие другие вещи - Или любая комбинация таких вещей
UI
— это “параметризованная” оболочка, которую “питает” и вызывает к “жизни” Model- Думайте о
UI
как о “визуальном” проявлении Model (Модели) - Model (Модель) — это где “живут” такие вещи как isFaceUp и cardCount (a не @State в
UI
) SwiftUI
заботится о том, чтобыUI
перестраивался всякий раз, когда Model (Модель) изменяется
Model (Модель) может быть одной структурой struct. Это может быть целая SQL база данных, полная всяких сущностей. Возможно, что это может быть какой-то код машинного обучения.
Это может быть похоже на REST API для Интернета. Это может быть почти что угодно.
Наша Model (Модель) — концептуальная вещь, это не просто одна структура struct, хотя в нашем приложении Memorize это будет действительно одна структура struct, так как у нас очень простое маленькое стартовое приложение. Но я не хочу, чтобы вы думали, что ваша Model (Модель) не может быть более мощной и сложной.
Что касается UI
части нашего приложения, то это на самом деле просто “параметризованная” оболочка, которую Model “кормит”. Одна из лучших фраз, которые я слышал о UI — это визуальное проявление Model, потому что Model — это то, чем реально является ваше приложение, это игра на запоминание Memorize, вот что это такое, так что вся эта логика игры находится в Model.
UI — это просто то, как вы показываете Model пользователю, то есть её визуальное проявление. Вам действительно хочется думать об этом именно так.
То, что мы разместили наши переменные isFaceUp и cardCount в @State, принадлежат Model. Всё это касается игры, в которую мы играем. Поэтому мы не хотим, чтобы они были в UI, и я постараюсь избавиться от них в UI, поместив их в нашу Model.
Одна из очень важных вещей, которые делает Swift
, супер важная его обязанность, заключается в том, чтобы обеспечить отражение в UI любых изменений в Model. Model отображается в UI. И для этого у Swift
есть огромная инфраструктура для этого.
В свою очередь ВАМ НЕ нужно нести ответственность за то, что все, что есть в вашей Model, отображалось бы в UI. Swift
всё это сделает за вас. Вам же просто нужно дать Swift
несколько подсказок о том, что в Model влияет на ваш UI. Как только вы сделаете это единожды, дальше волноваться об этом не придется.
Беспокоиться следует о том, чтобы разделить эти вещи: Model и UI.
Но если мы разделим Model и UI, как они будут между собой взаимодействовать? Потому что очевидно, что им нужно поговорить друг с другом.
Я свел это к трем различным способам коммуникации Model и UI. Возможно, существуют и другие способы, но большинство вещей уместилось бы в одной из этих трех категорий.
Model и UI
Подключение Model к UI
Существует несколько вариантов подключения Model к UI …
- Редко, но Model может быть просто @State в View (это минимум разделения, его практически нет)
- Model может быть доступна только через “привратника” (gatekeeper) — класс class “
View Model
” (полное разделение) - Существует “
View Model”
класс class, но Model все еще доступна View напрямую (частичное разделение)
Почти всегда этот выбор зависит от сложности Model. . .
- Model представляет собой SQL + struct(s) + что-то еще — скорее всего опция #2
- Model представляет собой простейший кусок данных и не имеющая практически никакой логики — скорее всего опция #1
- Что-то между опцией 1 и опцией 2 — опция #3
- Сегодня мы будем говорить об опции #2 (полное отделение).
- Мы называем такую архитектуру, которая подключает Model к UI таким образом, MVVM.
- Model — View — ViewModel
- Это основная архитектура для любого разумного по сложности
SwiftUI
приложения - Мы быстро взглянем на то, как использовать #3 (частичное разделение) путем минимальных изменений MVVM.
- Редко, но один из способов, каким можно подключить Model к UI, заключается в том, что Model (Моделью) является @State в View. Я имею в виду, что если вы всю Model, всю логику в вашем приложении разместите в @State в вашем View, то, очевидно, View может получить к ней доступ. Это крайне минимальное разделение. Я бы, наверное, не стал этого делать.
- Давайте поговорим о том, что мы будем делать в ближайшее время. Номер 2 заключается в том, что Model доступна для UI только через “привратника” (Gatekeeper). У нас будет привратник (Gatekeeper), class
ViewModel
, и работа этого “парня” — поддерживать безопасную коммуникацию UI и Model. Это основной способ, который мы будем использовать в наших приложениях, и этот способ называется MVVM. Номер 2 мы будем использовать в 99% случаев при создании приложений - Номер 3 является своего рода гибридом первых двух, то есть у нас есть этот привратник (gatekeeper), который мы называем
ViewModel
, но иногда у нас есть прямой доступ к Model. У нас будет public переменная var в Model, которая доступна UI и через неё UI на самом деле разговаривает с Model напрямую, прямо с игрой Memorize. По сути, это гибрид первых двух.
Итак, как узнать, какой из этих вариантов использовать?
Читать далее