На Лекции 14 курса Стэнфорда CS193p — «Developing Application for iOS» Spring 2020 («Разработка приложений для iOS». Весна 2020) Пол Хэгерти продолжает излагать темы, которые не являются обязательными на этом курсе, но могут реально понадобится студентам в создании полноценных финальных проектов. Лекция 14 посвящена очень важной «возможности SwiftUI
— интеграции с UIKit
.
UIKit
— это старый способ разработки приложений для iOS
. Когда появился SwiftUI
, то он в значительной степени делал всё, что делает UIKit
, но осталось всё же несколько “фишек” в UIKit
, которых сейчас нет в SwiftUI
, а вы бы хотели их использовать, поэтому в SwiftUI
появился специальный API
, позволяющий очень легко интегрировать в него UIKit
компоненты.
Если вы — уже действующий разработчик приложения для iOS
и у вас есть куча UIKit
кода, то, конечно же, вы бы хотели использовать его при переходе на SwiftUI
, так что этот API
интеграции вам также очень пригодится.
В UIKit
нет MVVM
, вместо этого там то, что называется MVC
(Model View Controller). В MVC
архитектуре Views как бы сгруппированы вместе и управляются тем, что называется Controller.
В SwiftUI
у нас нет никаких Controllers, там Views — это просто Views, и мы представляем их на экране, когда мы хотим. Но в UIKit
Views размещаются на экране совершенно по-другому. По сути, мы представляем на экране Controller, а уже Controller управляет своими Views. Из-за того, что у нас есть Controller интеграция между SwiftUI
и UIKit
требует 2-х точек интеграции.
Эти две точки интеграции очень похожи, одна из них — UIViewRepresentable, это SwiftUI
View, которое представляет UIKit
View, а другая точка — UIViewControllerRepresentable, также SwiftUI
View, но представляющее UIKit
Controller и все Views, которыми этот Controller управляет.
Кроме того, UIKit
является объектно-ориентированным. Это не функциональное программирование. Это совершенно другой Мир, он не декларативный, он не реактивный, ничего из этого в этом Мире нет. Он интенсивно использует концепцию, называемую делегированием (delegation). Поэтому, выполняя интеграцию между SwiftUI
и UIKit
, мы должны обеспечить делегатом delegate наши UIKit
View или Controller, чтобы они могли полноценно функционировать, потому что в большинстве случаев им нужен этот делегат delegate, чтобы делать что-то по существу.
Надо сказать, что Apple
создала на удивление простой API
для такой интеграции SwiftUI
и UIKit
и Пол Хэгерти подробно рассматривает его на двух демонстрационных примерах.
В одном демонстрационном примере он возвращается к приложению Enroute
, работающему с трекером полетов FlightAware, и в фильтре FilterFlights обеспечивает выбор аэропорта назначения destination
прямо с реальной Apple
карты. По сути, это демонстрация UIViewRepresentable, так как картой является UIKit
карта, называемая MKMapView.
В iOS 14
и SwiftUI 2.0
появился «родной» компонент Map, но пока он значительно уступает по функциональности MKMapView, так что использование интеграции в нашем случае вполне оправдано и в SwiftUI 2.0
.
Второй демонстрационный пример касается приложения EmojiArt
. В нем предлагается добавить еще один способ получения фонового изображения непосредственно с фотокамеры (.camera
) или из библиотеки фотографий (.photoLibrary
). В этом случае используется UIViewControllerRepresentable, потому что получение “картинки” с фотокамеры или из библиотеки фотографий предполагает размещение на UI
одного из этих MVC
, а в частности UIImagePickerController. Интеграция UIViewController немного отличается от интеграции UIView.
Оба демонстрационных примера будут иметь делегата delegate, так что вы сможете увидеть, как это интегрируется.
По ходу дела профессор демонстрирует два способа извлечения информации из методов делегата delegate. Один — с помощью @Binding, другой — с помощью замыкания.
Код демонстрационного примера с файловой системой для Лекции 14 находится на сайте курса CS193P и на Github для iOS 13 в папке Enroute L14 и EmojiArt L14.
Русскоязычный неавторизованный конспект Лекции 14, хронометрированный через каждые 5 минут, и представленный в виде PDF-файла, который можно скачать и использовать offline, а также в формате Google Doc доступны на платной основе.