SwiftUI заставляет вас принимать правильные решения при кодировании

Я изучаю SwiftUI или UIKit? Вопрос, который задают новые программисты iOS по всей планете после WWDC 2019. С чего мне начать? Я узнаю и то, и другое? Почти повсеместно в большинстве ответов, которые я читал, говорится о UIKit. SwiftUI мол не готов, никто им не пользуется. Нет. Я не согласен, хотя не по той причине, о которой вы, возможно, думаете.

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

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

Хорошо, но при чем здесь SwiftUI и UIKit, спросите вы. Давайте посмотрим на несколько практических примеров. Я начал изучать набор SwiftUI через несколько месяцев после его выхода. Сначала меня это иногда немного раздражало. Добавлю, пожалуй, что я не новый программист, я кодил более тридцати лет. Думаю, меня это раздражало, потому что это не позволяло мне продолжать практиковать некоторые мои плохие привычки. Поговорим о моих вредных привычках. Итак, переходим к нашему первому проекту SwiftUI. Это классическое приложение K&R Hello World.

import SwiftUI
struct SwiftUIView: View {
  var body: some View {
    Text("Hello, World!")
  }
}

В этом нет ничего плохого. Следующим нашим действием будет добавление второй метки. SwiftUI немедленно выйдет из строя и сообщит об ошибке.

Теперь, если вы делаете это с помощью UIKit, вы бы написали что-то вроде этого. Пример, к которому вы могли бы легко добавить вторую безошибочную метку. Итак, что не так с первым, и где здесь лучше всего кодировать, спросите вы.

class ViewController: UIViewController {
override func viewDidLoad() {
  super.viewDidLoad()
  let myLabel = UILabel(frame: CGRect(x: 100, y: 100, width: 100,   height: 100))
  myLabel.text = "Hello World"
  view.addSubview(myLabel)
  }
}

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

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

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

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

Это потому, что SwiftUI ограничивает количество элементов представления на представление до десяти. Кроме того, вам необходимо сгруппировать элементы в логические группы. Нет никаких технических причин, по которым Apple решила ограничить вас десятью элементами, кроме того факта, что это, безусловно, лучшая практика кодирования. Это лучшее ограничение кодирования, во многом похожее на то, что пометил бы один SwiftLint. Я говорю это, и я не работаю в Apple, но я искренне верю, что это было их намерением.

Приведем еще один пример. Вернемся к UIKit. Вам нужно вычислить значение, которое вы используете во внутреннем цикле, используя значение из внешнего цикла. Вот код, чтобы показать вам, о чем я говорю. Ca marche, как говорят по-французски. Но подождите, это хорошая практика кодирования.

class ViewController: UIViewController {
  override func viewDidLoad() {
  super.viewDidLoad()
  for col in 0 ..< 10 {
    let z = col * 10
    for row in 0 ..< z {
      let myLabel = UILabel(frame: CGRect(x: 100 + row, y: 100 + z, width: 100, height: 100))
      myLabel.text = "Hello World"
      view.addSubview(myLabel)
      }
    }
  }
}

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

struct ContentView: View {
  var body: some View {
    VStack {
      ForEach(0 ..< 10) { col in
        ForEach(0 ..< returnM(col)) { row in
          Text("Row \(row) \(row + col)")
        }
      }
    }
  }
}
func returnM(col: Int) -> Int {
  return col * 10
}

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

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

Еще один. Сейчас это может показаться маловероятным, но если вы попытаетесь добавить 11 групп к одному представлению, это тоже не сработает, такое же ограничение, как и для представлений для представления… но подождите, в UIKit таких ограничений нет. Это похоже на ограничение количества строк в методе. Это снова, безусловно, лучшая практика кодирования. SwiftLint проверит это ограничение, и вы тоже должны его соблюдать. Это лучшая практика кодирования.

Давай зададим вопрос еще раз. Я изучаю UIKit, SwiftUI или оба? Которая первая. В моей книге вам нужно сначала изучить SwiftUI, а затем UIKit. Это познакомит вас с идеей, которая необходима для структурирования кода, и вы не разовьете плохие привычки с самого начала, и вы не сделаете наоборот. Еще лучше, хотя это правда, что SwiftUI не поддерживает полный интерфейс WYSIWYG, чтобы вы могли кодировать все ручки и кнопки, которые делает UIKit, он поддерживает средства для кодирования ручек и кнопок UIKit через объекты, представленные UIR в SwiftUI. Итак, изучите SwiftUI, затем как включить в него UIKit через UIRepresentable objets и, наконец, изучите UIKit, в том числе с этим интерфейсом WYSIWYG в Xcode.