Для разработки iOS-приложений можно использовать два основных фреймворка: UIKit и SwiftUI. Однако при переходе со старого инструмента на новый, многие разработчики сталкиваются с трудностями, ведь парадигмы программирования у них сильно отличаются.

Цель статьи

Помочь разработчикам приложений для iOS понять различия между императивным и декларативным подходами к программированию, а также рассмотреть плюсы и минусы фреймворков UIKit и SwiftUI. Знакомство с ними необходимо для оптимизации процесса разработки и создания продукта высокого качества.

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

Почему я над этим задумался?

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

Темпы роста команды были очень высокими. Мы нанимали крутых инженеров, но большинство из них не сталкивались в своей работе со SwiftUI. Поэтому им приходилось переучиваться в процессе адаптации, набивать шишки на код-ревью и изучать новую технологию на ходу. База знаний о SwiftUI для погружения новых сотрудников у нас отсутствует. Эта ситуация дала понять, что большинство разработчиков сталкиваются с одной и той же проблемой: сложностью перехода с императивного на декларативный подход. Это подтолкнуло меня сначала подготовить доклад для внутреннего митапа Ozon, а позже — написать эту статью.

Содержание

Императивный и декларативный подходы

Рассмотрим два подхода к программированию: императивный и декларативный.

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

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

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

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

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

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

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

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

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

Примеры кода

 // Императивный подход
func sumOfSquaresI(array: [Int]) -> Int {
    var sum = 0
    for number in array {
        let square = number * number
        sum += square
    }
    return sum
}


// Декларативный подход
func sumOfSquaresD(array: [Int]) -> Int {
    array.map { $0 * $0 }.reduce(0, +)
}

В этих примерах мы решаем одну и ту же задачу — вычисление суммы квадратов чисел в массиве — но делаем это по-разному: с помощью императивного и декларативного подходов.

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

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

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

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

Устаревающий UIKit ????‍???? vs Новый SwiftUI ????

В этом разделе мы рассмотрим два фреймворка для разработки пользовательских интерфейсов для iOS: устаревающий UIKit и новый SwiftUI. Мы разберём их особенности и отличия, а также рассмотрим примеры кода на UIKit и SwiftUI, и какой код писать точно не нужно.

UIKit — это фреймворк, который применяется для создания пользовательского интерфейса в iOS-приложениях с 2007 года. Он использует императивный подход к разработке, на который опираются программисты, описывая на Swift и Objective-C, как создавать и настраивать элементы интерфейса. Вы определяете все свойства каждого элемента: положение на экране, размеры, цвета, шрифты и т. д. UIKit предоставляет великолепный инструментарий, однако требует высокого уровня квалификации для работы с ним.

SwiftUI Apple представила в 2019 году. Это фреймворк, который реализует декларативный подход к разработке пользовательского интерфейса. Он даёт возможность описывать элементы интерфейса, используя концепцию зависимостей данных между ними, а не процесс их создания и настройку. Это означает, что каждый элемент интерфейса зависит от данных, которые ему передаются. Если эти данные изменяются, то соответствующие элементы интерфейса автоматически обновляются, что является однонаправленным подходом в программировании.  Это означает, что изменения в модели данных автоматически обновляют представление, но обратного не происходит.

Чтобы лучше понимать особенности SwiftUI, полезно знать о связке с реактивным программированием и библиотекой Combine.

Реактивное программирование — это концепция, в которой данные представляются в виде потоков (streams), автоматически обновляющихся при изменении состояния представления. А библиотека Combine позволяет использовать реактивный подход в SwiftUI, упрощая работу с потоками данных.

Действие -> Состояние -> Отображение

SwiftUI — это новый инструмент для разработки пользовательского интерфейса iOS-приложений, который быстро набирает популярность у разработчиков. Он прост в использовании и гибок, что позволяет писать код значительно быстрее, чем со старым UIKit.

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

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

Давайте рассмотрим процесс создания кнопки в обоих фреймворках.

Императивный подход на UIKit

final class MyViewController: UIViewController {
    let myButton = UIButton(type: .system)


    override func viewDidLoad() {
        super.viewDidLoad()


        myButton.frame = CGRect(x: 100, y: 100, width: 100, height: 50)
        myButton.setTitle("Press me", for: .normal)
        myButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        view.addSubview(myButton)
    }


    @objc func buttonTapped() {
        print("Button tapped!")
    }
}

Декларативный подход на SwiftUI

struct MyView: View {
    var body: some View {
        Button("Press me") {
            print("Button tapped!")
        }
        .frame(width: 100, height: 50)
        .position(x: 100, y: 100)
    }
}

Оба этих примера демонстрируют создание кнопки, нажатие на которую выводит сообщение “Button tapped” на консоль. Однако декларативный подход на SwiftUI гораздо более лаконичный и понятный. Вместо того чтобы настраивать каждый аспект кнопки отдельно, мы описываем кнопку в терминах её желаемых свойств — и SwiftUI самостоятельно обеспечивает реализацию. Это может существенно ускорить процесс разработки и уменьшить количество ошибок.

Кроме того, SwiftUI в связке с Combine позволяет нам использовать многие удобные функции, такие как, например, автоматические обновления интерфейса при изменении состояния, что делает создание пользовательских интерфейсов ещё более простым и эффективным.


Теперь рассмотрим процесс создания таблиц в обоих фреймворках.

TableView на UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    let data: [String] = ["Первый элемент", "Второй элемент", "Третий элемент"]
    var tableView: UITableView = UITableView()
  
    override func viewDidLoad( ) {
        super .viewDidLoad()
        tableView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        tableView.delegate = self
        tableView.dataSource = self
        self.view.addSubview(tableView)
    }
  
    func numberOfSections(in tableView: UITableView) -> Int { return 1 }
  
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return data.count }
  
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = data[ indexPath.row]
        return cell
    }
  
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("Выбран элемент \(data[ indexPath.row])" )
    }
}

По коду понятно, что реализовать таблицу на UIKit довольно сложно. 

Таблица на SwiftUI

struct ContentView: View {
    let data: Set<String> = ["Первый элемент", "Второй элемент", "Третий элемент"]
    
    var body: some View {
        List(data, id: \.self) { item in
            Text(item)
        }
    }
}

А вот реализация таблицы на SwiftUI не требует стольких усилий — код выглядит куда проще. 

Хороший пример с плохим кодом

import SwiftUI


struct ContentView: View {
    var label = Text("Hello, World!")
    label = label.font(.system(size: 16))
    label = label.background(.red)
    
    var button = Button {
        print("Button tapped")
    } {
        Text("Tap Me")
            .font(.headline)
            .foregroundColor(.white)
            .padding()
            .background(Color.blue)
            .cornerRadius(5)
    }
    
    button.frame(width: 120, height: 44)
}

Данный код на SwiftUI нарушает структуру View, поскольку в нём нет её объявления и функции body, которая должна содержать описание интерфейса. Переменные label и button объявлены вне функции body, что может вызвать ошибки при компиляции. Кроме того, использование модификаторов неоптимально: переменная label переопределяется три раза, что затрудняет чтение кода и может привести к утере значений его свойств. Помимо этого, кнопка не связана с функцией body и не обрабатывает события. Подобный код будет сложно поддерживать, он требует много времени на написание и ревью. Он не будет соответствовать стандартам качества кода и не будет принят инженерами.

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

Итак, SwiftUI — это новый инструмент для разработки пользовательского интерфейса с низким порогом входа и декларативным подходом к программированию, который упрощает создание пользовательского интерфейса. Однако при наличии многолетнего опыта работы с UIKit многие разработчики предпочитают продолжать работать с ним. Но ведь мы должны быть готовы меняться и адаптироваться к новым технологиям, чтобы оставаться на плаву в быстро меняющемся мире iOS-разработки.

Меняйся или сдохни

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

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

Преимущества и недостатки фреймворков

Некоторые инженеры, которые приходят к нам в Ozon Tech, считают, что SwiftUI — полная фигня и им не стоит пользоваться, тем более в коммерческой разработке. Другие же уверены, что UIKit  — это безнадёжно устаревшая технология динозавров. И все они правы! Но не совсем.

Мы переходим к основной части моей работы. Я поговорил с большим количеством экспертов, провёл масштабное исследование и выписал неопровержимые плюсы и минусы SwiftUI и UIKit. Давайте на них посмотрим:

Посмеялись — и хватит ????

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

 

SwiftUI ????

UIKit ????‍????

Скорость вёрстки

+

-

Совместимость с легаси-кодом

-

+

Дебаггинг

-

+

Мультиплатформенность

+

-

Поддержка сообщества

-

+

Количество кода

+

-

Совместимость с Modern Concurrency 

+

-

Поддерживаемость

-

+

Быстродействие

+

-

Скорость вёрстки: SwiftUI +, UIKit -

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

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

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

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

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

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

Совместимость с легаси-кодом: SwiftUI -, UIKit +

UIKit появился раньше, чем SwiftUI, он работает с Objective-C и Swift, что обеспечивает совместимость с готовым к использованию легаси-кодом. 

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

Однако, в отличие от Swift, Objective-C не поддерживает жирные структуры. Следовательно, нет способа написать пользовательский интерфейс с помощью SwiftUI и импортировать его в приложение, написанное на Objective-C. Это означает, что разработчики, которые хотят использовать SwiftUI, должны перейти на Swift и создать новое приложение с нуля, если хотят использовать весь потенциал фреймворка.

Дебаггинг: SwiftUI -, UIKit +

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

Одним из выборов разработчиков является выбор между двумя фреймворками: SwiftUI и UIKit. Каждый из них имеет свои преимущества и недостатки при дебаггинге.

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

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

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

Мультиплатформенность: SwiftUI +, UIKit -

SwiftUI был создан как фреймворк для мультиплатформенной разработки приложений, что позволяет использовать единый код для создания приложений для разных платформ: iOS, macOS, watchOS и tvOS. UIKit ориентирован на создание приложений только для iOS.

Поддержка сообщества: SwiftUI -, UIKit +

UIKit является «взрослым» общепризнанным фреймворком, который объединяет большое сообщество разработчиков и множество инструментов и библиотек для его использования. SwiftUI только появился и его сообщество пока ещё не такое развитое и большое, как у UIKit.

Количество кода: SwiftUI +, UIKit -

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

Совместимость с Modern Concurrency: SwiftUI +, UIKit -

SwiftUI представляет собой фреймворк, который полностью поддерживает Modern Concurrency с помощью новых Swift API, таких как async/await и Combine. UIKit же как старший фреймворк может не всегда соответствовать современным требованиям к асинхронному программированию и требовать дополнительных усилий для написания асинхронного кода.

Поддержка версий: SwiftUI -, UIKit +

SwiftUI был представлен в 2019 году вместе с iOS 13, поэтому поддерживает только устройства на ней и более новых версиях. Это означает, что разработка приложения с использованием SwiftUI может стать проблематичной, если требуется поддержка более старых версий iOS.

UIKit в дополнение к поддержке iOS 13 и более новых версий поддерживает и более ранние версии iOS. Это означает, что с ним разработчики могут создавать приложения, которые будут работать на более старых устройствах и версиях платформы iOS.

Быстродействие: SwiftUI +, UIKit -

SwiftUI предоставляет более быстрое и эффективное развитие своего инструментария по сравнению с UIKit. Он ориентирован на использование структур, тогда как UIKit использует классы для создания пользовательского интерфейса. Использование структур делает код на SwiftUI более лёгким, читабельным и удобным в работе. Структуры в Swift хранятся в стеке, а не в куче, как классы, — это обеспечивает более эффективное использование памяти (более быстрое выделение и освобождение).

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

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

Кто же победил?

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

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

При работе с версткой пользовательских интерфейсов, мы можем использовать фреймворки UIKit или SwiftUI. Однако, важно понимать, что каждый из них имеет свои особенности и специфику работы.

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

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

В этой статье мы рассмотрели:

  • особенности императивного и декларативного подходов программирования; 

  • особенности фреймворков UIKit ????‍???? и SwiftUI ????;

  • плюсы и минусы фреймворков UIKit ????‍???? и SwiftUI ????.

Несмотря на то, что дедуля UIKit не использует декларативный подход, он является очень мощным и гибким инструментом для создания пользовательского интерфейса iOS-приложений, и не стоит списывать его со счетов. Но сейчас у него есть серьёзный конкурент в виде относительно нового фреймворка, который впечатляет своими фичами, взять хотя бы сниженный порог входа в разработку. Может повториться история Objective-С и Swift, ведь реальность такова, что Apple движется в сторону технологических улучшений своих инструментов для разработки, и увеличение популярности SwiftUI и переход на его сторону многочисленного комьюнити — вопрос времени.

Полезные материалы

1. Фреймворк Carbon, который даёт возможность потрогать декларативный подход в UIKit. Это библиотека для создания пользовательских интерфейсов на основе компонентов UITableView и UICollectionView, вдохновлённая SwiftUI и React.

2. Реактивное программирование с Combine: тут и тут

3. Доклад Руслана Кавецкого из Agora «Избавляемся от старья и переходим на SwiftUI».

4. Статья «SwiftUI по полочкам».

*Хотел бы поблагодарить за помощь в написании статьи моих коллег и друзей:

Сергей Фирсов

Василий Усов

Максим Гришутин

Комментарии (26)


  1. storoj
    21.06.2023 08:09

    Про быстродействие чушь какая-то, и вообще в статье много сомнительных заявлений


    1. gnatyuk_sergey Автор
      21.06.2023 08:09
      +1

      Привет!????
      Давайте разберем конкретные моменты, мне это очень поможет????


      1. ws233
        21.06.2023 08:09
        +1

        А пожалуйста.

        Вы "быстродействие" обосновываете "более быстрым и эффективным развитие фреймворка", "лёгкостью, читабельностью и удобством в работе", "опытом программиста" и т.д. Это все, естественно, не связано.

        Если оставить только связанное, то остаются только структуры против классов.

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

        Сконцентрируемся на том факте, что SwiftUI – это всего лишь обертка поверх UIKit. Т.е. все ваши структуры под капотом все равно создают соответствующие классы UIKit и работают с ними. Т.е. никакого выигрыша в производительности Вы не получите просто по одной причине: вместо того, чтобы работать только лишь с одними классами, вы еще создаете, модифицируете, гоняете по памяти, удаляете эти самые структуры-обертки-описания этих самых классов. Большее количество работы ну никак не может быть быстрее, чем меньшее количество работы. Согласны?

        Теперь про "сборку мусора". Ее на iOS нет. Вместо нее используется механизм подсчета ссылок. Вопрос, который проясняют с каждым джуном на собеседовании. Этот механизм считается очень быстрым и имеющим нулевые затраты на управление памятью (на самом деле не нулевые, но близкие к нулю). При этом точно такой же механизм используется и для определения момента удаления структуры из стека. Поэтому этот аргумент в пользу быстродействия SwiftUI и структур тоже сомнителен.

        Но да, спасибо за проделанную работу. Осталось ее подкорректировать и получится очень классная статья-сравнение. Можно будет ссылаться на нее и на Вас в моих дискуссиях про 2 технологии :)


        1. awoland
          21.06.2023 08:09
          +2

          Полностью согласен со всем сказанным. Собственоо эта же утверждение "лежит на поверхности" данной статьи в несколько "подсознательной" форме. Достаточно детально проанализировать смысл двух цитат из этой статьи:
          "UIKit предоставляет великолепный инструментарий, однако требует высокого уровня квалификации для работы с ним."
          "SwiftUI... Благодаря такому подходу, разработчики могут писать менее сложный код."
          Не люблю холиварных вопросов, но суть ясна - с одной стороны сложный профессиональный интрумент с высоким порогом использования (требованиями к профессионализму), а с другой облегчённое упрощение с низким порогом входа для использования ...


        1. vitalist84
          21.06.2023 08:09

          Сконцентрируемся на том факте, что SwiftUI – это всего лишь обертка поверх UIKit

          откуда такая информация?


          1. ws233
            21.06.2023 08:09

            1. в интернетах пишут. раз. два - swiftui code is converted to uikit views behind the scenes. больше искать не стал. поищите, пожалуйста, сами.

            2. возможность транслировать код из SwiftUI в UIKit и обратно тоже как бы намекает.

            3. Ну и я собрал маленький пример. Скрины ниже.

            Hidden text

            Да, никто не запрещает Эплу полностью переписать внутреннюю реализацию без использования UIKit, но пока это не так. Планов по переписыванию я не встречал.

            Да, на других платформах под SwiftUI будут другие фреймворки. Но смысл тот же - это всего лишь обертка.

            Так что? Исправите статью под многочисленные комментарии к ней?


            1. vitalist84
              21.06.2023 08:09

              ну похоже на смешанную конструкцию, простое и новые вещи, типа Text, VStack, HStack и т. д. реализованы каким-то новым способом, а сложные вещи типа навигации, таблиц работают через UIKit, так как там все давно отточено и оптимизировано. Ну и наверное в RunLoop и весь флоу на UIKit схеме работает. Однако есть подозрение что постепенно Apple это все будет передеывать на новые рельсы.


              1. ws233
                21.06.2023 08:09

                Об этом я и написал, да. Что это вряд ли будет быстрее. Скорее медленнее.


  1. Vladosius
    21.06.2023 08:09
    +1

    Какие техники и подходы можно применить для эффективного дебаггинга в SwiftUI, несмотря на ограничения инструментов?


    1. gnatyuk_sergey Автор
      21.06.2023 08:09

      Привет!????

      Если мы не берем в расчет старые добрые способы в виде принтов и брейкпоинтов, можно попробовать использовать стороннюю библиотеку ViewInspector ну и конечно же SwiftUI Previews дает много возможностей, просто не всегда получается запускать превью корректно, особенно в большом проекте




  1. MeGaPk
    21.06.2023 08:09
    +1

    в SwiftUI очень весело фиксить "новшевста" эпла, которые они привносят с минорной версией iOS. Допустим в 16.0 нормально работала клавиатура на вьюхе, в 16.1 уже поломана... и таких микро моментов полно и фиксить приходится обходными путями... Если в UIKit куда проще эпол моменты починить, то в SwiftUI не так.


    1. gnatyuk_sergey Автор
      21.06.2023 08:09

      Привет!????

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




  1. ftp27
    21.06.2023 08:09
    +2

    Примеры приведены сомнительные. Я уже не помню когда использовал UITableView для верстки хоть каких то компонентов, даже для списков лучше подходит UICollectionView с кастомным layout который будет в точности соответствовать требуемым макетам. Если я не ошибаюсь, коллекции в SwiftUI завезли совсем недавно, раньше были сухонькие списки, что ограничивает нас не только 13м iOS-ом, а ощутимо позже. Да, процент юзеров на старых iOS ничтожно мал, что можно и поднять минимальную версию в приложении, но вы же Ozon, логично предположить, что вам нужен максимальный охват.

    Касательно "Modern Concurrency", то вам ничего не мешает его использовать с UIKit, но пихать такую логику в View компоненты выглядит сомнительным.

    С мультиплатформенностью тоже не соглашусь. Изначально TvOS и WatchOS работали на UIKit, даже в MacOS какие никакие переводы делали. Точно могу сказать, что TvOS отлично работает с приложениями на UIKit, да надо накрутить немного другие события, но код будет один и тот же.


    1. BarredEwe
      21.06.2023 08:09
      +2

      Коллекции aka LazyVGrid, уже довольно давно есть. iOS 14.0 - SwiftUI 2.0


    1. gnatyuk_sergey Автор
      21.06.2023 08:09

      Привет! ????

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

      Тут скорее про то, что SwiftUI позволяет использовать Modern Concurrency в более удобной и эффективной форме.

      Я понимаю вашу точку зрения относительно мультиплатформенности, и в некоторых случаях TvOS и WatchOS могут работать с приложениями на UIKit. Однако, мультиплатформенность может требовать создания различных интерфейсов для разных платформ, и в таком случае использование SwiftUI может быть полезным ????


      1. ftp27
        21.06.2023 08:09

        С чатом GPT ответы генерите ????


      1. ws233
        21.06.2023 08:09
        +1

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

        Проще написать отдельный UI для TVOS, watchOS и iOS в горизонтальной и вертикальной ориентации, чем пытаться описать все это единым языком с лапшой условий.

        По Modern Concurrency. Вам ничего не мешает добавить подобный синтаксис к ObjC и использовать его с ObjC.


        1. gnatyuk_sergey Автор
          21.06.2023 08:09

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


  1. BackLaN
    21.06.2023 08:09

    А зачем в UIKit создавать элементы прямо в коде, это какой-то особый мазохизма? Есть же визуальный дизайнер форм, кстати в дизайнере можно и таблицы и списки делать, вообще без кода. Так же массив биндится с формой, если таблица то колонка биндится к словарю, а в массиве хранится список словарей. Все изменения в форме автоматически отражаются на экране, а если меняем данные на экране, все изменения отражаются в связанном массиве автоматом. И для этого не надо ни одной строчки кода. И код в результате будет, короче чем с SwiftUI. Вы дизайнером форм то в связке с UIKit пользоваться умеете?


    1. BarredEwe
      21.06.2023 08:09
      +1

      С одной стороны визуальный дизайнер форм, а с другой большие команды разработки. Одно с другим практически не совместимо ????

      PS: Мерж конфликты в xml, это своеобразный фетиш


      1. gnatyuk_sergey Автор
        21.06.2023 08:09

        Плюсую много раз про конфликты????


      1. ws233
        21.06.2023 08:09

        Эта проблема давным давно решена. Разделяй и властвуй. Не нужно весь UI приложения пытаться запихнуть в 1 xml-файл. Этих файлов может быть много. Тогда вероятность, что 2 разработчика полезут в один xml-файл резко сократится. А практики установления владения над кодом эту вероятность вообще к нулю сводят. Никаких проблем. Проверено на практике.


        1. BarredEwe
          21.06.2023 08:09

          Возможно так, вероятность сократится, будет стремиться к нулю. Но гарантировать что вероятность этого нулевая, достаточно сложно. А когда это стреляет, то разработчик вынужден править код, написанный не на его основном языке. Обычно еще время сборки увеличивается, проверял лет 5 назад с xib и storyboards.


    1. gnatyuk_sergey Автор
      21.06.2023 08:09

      Привет!????

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

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

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


  1. ws233
    21.06.2023 08:09
    +2

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

    Однако, в отличие от Swift, Objective-C не поддерживает жирные структуры. Следовательно, нет способа написать пользовательский интерфейс с помощью SwiftUI и импортировать его в приложение, написанное на Objective-C. Это означает, что разработчики, которые хотят использовать SwiftUI, должны перейти на Swift и создать новое приложение с нуля, если хотят использовать весь потенциал фреймворка.

    В корне неверно. SwiftUI полностью совместим с ObjC. У Элла есть документация, какие оберточки Вам нужно сделать, чтобы иметь возможность использовать SwiftUI в ObjC.

    1. Про скорость верстки очень неоднозначный момент. Да, в простых синтетических примерах, где надо только фрейм поменять, тут SwiftUI нет конкурентов. Но как только мы переходим в область комплексного UI и UX, так сразу начинаются проблемки и преимущество в скорости верстки резко превращается в мощный такой минус, перекрывающий полученный до этого выигрыш.


    1. gnatyuk_sergey Автор
      21.06.2023 08:09

      Привет! ????
      Спасибо большое за ваш отзыв! Для меня это очень важно!

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

      Было пару моментов, когда сложные интерфейсы хотелось сделать именно с использованием UIKit, но это скорее исключение из правил, пока нам удается использовать решения на SwiftUI в нашем проекте, даже со сложным интерфейсом????