Как программировать под Swift. Архитектура и модульный подход

Информатор avatar | 28
FavoriteLoading В закладки
Как программировать под Swift. Архитектура и модульный подход

Возвращаемся к циклу статей о программировании на Swift. Теперь поговорим про главное.

При поддержке знатоков разработки приложений из e-Legion, мы создали калькулятор калорий. Сегодня сосредоточимся на том, как организуется код внутри приложения. Это называют его архитектурой.

Некоторые из вас уже знают, что в основе любого iOS-приложения лежит архитектурный шаблон MVC. Для тех кто не знает — вот пояснение:

M — Model (данные). Их мы в красивом виде отображаем в интерфейсе и обновляем при пользовательском вводе.

V — View (интерфейс). То, что видит пользователь. Графическое отображение тех самых данных (M). Пользователь, взаимодействуя с интерфейсом, обновляет данные.

C — Controller. Промежуточный слой между интерфейсом и данными. Обеспечивает двухстороннее взаимодействие M с V.

Определённые фрагменты кода отвечают за выполнение определённых задач. Так, одна функция может отвечать за набор текста в текстовом поле, а другая – за обработку введённой информации. Рассмотрим пример нашего FirstViewController. Сам контроллер должен управлять отображением информации через view и сообщать модели о действиях пользователя.

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

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

Цель сегодняшнего урока — заложить понятие модульной разработки и применить этот принцип в нашем калькуляторе калорий.

Если сейчас мы взглянем на наше приложение, то увидим, что вся логика сосредоточена в контроллере. В методе-обработчике нажатия кнопки происходит вычисление значений BMI/BMR. Эту часть кода явно можно вынести в отдельный программный модуль, например, класс. Давайте запустим Xcode и создадим новый класс: New File->Source->Swift File->Next

Называем его Calc (калькулятор) и жмем Create.

Вы создали новый файл. В нем после строчки import Foundation впишите следующее:

Класс создан, теперь надо добавить в него метод (например, calculateBodyMassIndexAndRate), который вычисляет BMI/BMR относительно роста, веса и т.д. Но прежде чем приступить к реализации метода, давайте немного подумаем. Тот код, что сейчас находится в обработчике нажатия кнопки сильно зависит от интерфейсных элементов. Мы не можем просто взять и перенести его внутрь Calc, поскольку внутри нового класса нет и не должно быть доступа к интерфейсу пользователя, а должны быть только операции над данными. Решить эту проблему можно, добавив в наш метод необходимые параметры:

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

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

Отлично, следующим шагом давайте уже перенесем код из контроллера, заменив данные интерфейсных элементов на параметры input:

По аналогии с CalcInputData можно создать класс CalcOutputData, в котором будут храниться вычисленные значения BMR/BMI.
Мы не будем подробно останавливаться на самом алгоритме, достаточно сказать, что он использует входные данные, определяя по ним коэффициенты для вычислений. Подробно остановимся на последних строчках. Для того чтобы вернуть из метода значение, мы пишем return <значение>. Но что делать если результатом работы являются сразу несколько значений?

Есть два пути. Первый — то, как реализовано выше, т.е. создание отдельного класса для выходных данных (CalcOutputData), а второй способ — использование так называемых кортежей (tuples). Кортежи – это упорядоченные наборы значений, их использование поддерживается языком Swift. Их можно использовать, чтобы возвращать несколько значений одной функцией. Используя кортеж, мы можем обойтись без введения нового класса и упростить:

до:

А тип возвращаемого значения изменится c -> CalcOutputData на -> (Int, Int)

Отлично! Теперь у нас есть независимая сущность “Калькулятор”, которая для остальных программных частей представляет собой классический черный ящик:

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

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

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

Финальный аккорд.

Прежде чем перейти к завершающему действию, нужно ненадолго остановиться на таком теме, как конструкторы. У каждого класса помимо тех методов, которые мы пишем внутри, есть один или несколько методов, которые уже в нем присутствуют. Эти методы называются конструкторами, и они отвечают за создание экземпляров класса. Вызываются они по имени класса, то есть если класс называется Class, то вызов конструктора будет выглядеть как Class(). Конструктор всегда возвращает новый экземпляр класса. В конструктор как и в обычный метод можно передавать параметры, поэтому их может быть несколько.

Для вызова метода calculateBodyMassIndexAndRate из калькулятора, сперва нужно с помощью конструктора создать экземпляр класса, и, обратившись к нему вызвать непосредственно метод:

Обратите внимание, поскольку возвращаемое значение из метода это tuple (кортеж), то его внутренние значения доступны по индексу – 0, 1, 2 и т.д. Также хочется заострить ваше внимание на том, как формируется итоговая строка. В swift есть возможность удобного форматирования строк, без вызова дополнительных методов. Достаточно внутрь строки вставить конструкцию \(…) и внутри скобок записать требуемое выражение. В нашем случае в строку подставляются значения BMR/BMI из кортежа.

Итог

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

На текстом трудился Георгий Касапиди — iOS-разработчик e-Legion. Компания является лидером на рынке заказной мобильной разработки в Европе, входит в состав холдинга DZ Systems. За 9 лет существования были созданы приложения для РайффайзенБанка, Яндекса, Меги, Банка Москвы, Первого Канала, Sports.ru, Mail.Ru Group и многих других компаний.

1 Звезд2 Звезды3 Звезды4 Звезды5 Звезд (2 голосов, общий рейтинг: 5.00 из 5)
undefined
iPhones.ru
Возвращаемся к циклу статей о программировании на Swift. Теперь поговорим про главное. При поддержке знатоков разработки приложений из e-Legion, мы создали калькулятор калорий. Сегодня сосредоточимся на том, как организуется код внутри приложения. Это называют его архитектурой. Некоторые из вас уже знают, что в основе любого iOS-приложения лежит архитектурный шаблон MVC. Для тех кто не знает...
Прокомментировать

🙈 Комментарии 28

  1. Semplx avatar
    Semplx12 октябрь 2015
    10

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

  2. iy y yi avatar
    iy y yi12 октябрь 2015
    4

    А я давно ждал продолжения. Сейчас надо старые статьи вспомнить.

    Bonifaciy61 avatar
    Bonifaciy6113 октябрь 2015
    0

    @iy y yi, аналогично =)

    i.band avatar
    i.band15 октябрь 2015
    0

    @iy y yi, не проще посмотреть курс Stanford cs193p (в сети есть перевод всех лекций уже)?

  3. alkal avatar
    alkal12 октябрь 2015
    3

    А я все удивлялся почему же у Райффайзена настолько отвратительное мобильное приложение. Оказывается они до сих пор не удосужились создать свой отдел мобильных разработок, чтобы регулярно модернизировать программу.
    Учиться надо у ТКС и Сбера, хотя первый немного привлекательнее.

  4. iCid avatar
    iCid12 октябрь 2015
    12

    блин, ну вот этого хоть не надо…

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

    абсолютно бесполезная статья

    что такое класс? что такое метод? да что такое тип вообще? слова, чтобы сайт казался более технологичным (заумным), чем на самом деле есть?

    herzinberg avatar
    herzinberg12 октябрь 2015
    2

    @iCid, немного не согласен) Я вот знаю и метод, и класс, и свойство даже, циклы всякие знаю, кейсы, на перле иногда пищу, сиквельные запросы пилю, верстку иногда правлю, знаю про дивы, видео и аудио потоки, про нод, про вебсокеты и много чего)) С ООП хорошо знаком, хотя я не кодер)) Почитать любопытно было) Так что не все так плохо, как вам кажется, не все тупые, видимо) Не вижу ничего страшного в статье)

    iCid avatar
    iCid13 октябрь 2015
    0

    @herzinberg, при чем здесь “тупые”? поймите, это просто занимает очень много времени

    например, я могу сказать “я знаю ПРО квантовую механику”. это не дает мне возможность рассчитывать спины элементарных частиц. прочитав одну статью про уравнения Гайзенберга, с примерами этих уравнений, я все равно не научусь ничему новому. может и будет “любопытно” (посмотреть на красивые формулы =) ), но ничего более.

    herzinberg avatar
    herzinberg13 октябрь 2015
    0

    @iCid, много времени у кого?)) У вас?)

    iCid avatar
    iCid13 октябрь 2015
    0

    @herzinberg, фейловая попытка троллинга?

    в чем, собственно, вопрос? какая разница у кого?

    спецом для вас перефразирую: чтобы научится программировать (хотя бы даже быдлокодить) уйдут годы. nuff said

    herzinberg avatar
    herzinberg13 октябрь 2015
    0

    @iCid, пвахахах)) Все зависит от человека, у кого годы, у кого месяцы, а кому-то не дано) Вы главное не нервничайте так))))) Миру мир!))))

    iCid avatar
    iCid13 октябрь 2015
    0

    @herzinberg, смейтесь, смейтесь, а заодно загуглите по картинкам dunning-kruger effect и посмотрите график.
    смею сделать вывод, что вы – либо вротмненоги эксперт, либо в самом начале пути.

    herzinberg avatar
    herzinberg13 октябрь 2015
    0

    @iCid, я вот на личности не перехожу) Больше добра, исид) Не будь таким злым)

    iCid avatar
    iCid13 октябрь 2015
    0

    @herzinberg, я вас не оскорблял и не пытался. просто, вы говорите несуразицу ровно по этому графику.

    herzinberg avatar
    herzinberg13 октябрь 2015
    0

    @iCid, сейчас начнем медиа сервер по webrtc делать, я к тебе обращусь – всю суразицу мне расскажешь! Скинь контакты! Peace!

    iCid avatar
    iCid13 октябрь 2015
    0

    @herzinberg, нет, спасибо

    (“пойдем выйдем” XXI века? весело, чо)

    herzinberg avatar
    herzinberg13 октябрь 2015
    0

    @iCid, я говорю, помоги разобраться с написанием кода, а ты мне какие-то пойдем выйдем)) Меньше графиков смотри в гугле, студент))

  5. beginerX avatar
    beginerX12 октябрь 2015
    1

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

  6. WiND avatar
    WiND13 октябрь 2015
    5

    как_нарисовать_сову.jpg

    Еще два “респекта” за сорцы в картинке и отсутствие возможности скачать готовый проект.

  7. Silmaril avatar
    Silmaril13 октябрь 2015
    0

    Я бы (что касается структуры данных и вычислений) сделал так:

    struct BodyData {

    var age: UInt
    var height: Double
    var weight: Double
    var isMale: Bool
    var numberOfWorkouts: UInt

    init(age: UInt = 0, height: Double = 0, weight: Double = 0, isMale: Bool = true, numberOfWorkouts: UInt = 0) {
    self.age = age
    self.height = height
    self.weight = weight
    self.isMale = isMale
    self.numberOfWorkouts = numberOfWorkouts
    }

    var bmr: Double {
    var bmr: Double
    if isMale {
    bmr = 88.362 + 13.397 * weight + 4.799 * height – 5.667 * Double(age)
    } else {
    bmr = 447.593 + 9.247 * weight + 3.098 * height – 4.330 * Double(age)
    }
    switch numberOfWorkouts {
    case 0..<1:
    bmr *= 1.375
    case 1..<4:
    bmr *= 1.55
    case 4.. 0 {
    return weight / pow(height / 100, 2)
    } else {
    return 0
    }
    }

    }

    Кроме того конвертация строк в числа в Swift 2.0 уже не будет работать. Нужно к примеру так:

    var bodyData = BodyData()

    if let age = UInt(ageTextField.text ?? “”, radix: 10) {
    bodyData.age = age
    }

    if let height = Double(heightTextField.text ?? “”) {
    bodyData.height = height
    }

    Silmaril avatar
    Silmaril13 октябрь 2015
    0

    @Silmaril, блин что-то все по плыло

  8. Pavel Loskutov avatar
    Pavel Loskutov13 октябрь 2015
    1

    О, так это я теперь и на Свифте умею програмировать!

    ozyab avatar
    ozyab13 октябрь 2015
    1

    @Pavel Loskutov, точняк! Теперь можете отбивать клиентов у автора статьи.

  9. olegdenega avatar
    olegdenega13 октябрь 2015
    0

    Код на картинке – это, конечно же, пять баллов + путешествие в интернет прошлого века)

  10. Vanka_Feelgood avatar
    Vanka_Feelgood13 октябрь 2015
    0

    Пишите ещё. А еще лучше создайте отдельную рубрику о программировании.

    Freeman302 avatar
    Freeman30213 октябрь 2015
    0

    @Vanka_Feelgood, а смысл? Всё равно раз в полгода пишут об этом. Я первую статью по Swift просто сразу забил в закладки, а сам попёр учить Objective-C.

  11. bykoff avatar
    bykoff13 октябрь 2015
    0

    Спасибо за статью, мне понравилось. Нас много, интересов много. Кому интересно – тот читает, кому не интересно пусть не читает. Но вот зачем нытьё разводить по типу: «ой зачем вы это написали», не нравится – не читай! Такое впечатление, что вы деньги за эту статью заплатили, прочитали, а тут вам нате «типичное не то». Хватит брюзжать.

    iCid avatar
    iCid13 октябрь 2015
    1

    @bykoff, уверен, если здесь будут постить рецепты кексиков с шоколадом, найдется много солидарных с вами людей

Вы должны авторизоваться или зарегистрироваться для комментирования.

Нашли орфографическую ошибку в новости?

Выделите ее мышью и нажмите Ctrl+Enter.

Как установить аватар в комментариях?

Ответ вот здесь