Лучшие среды разработки для swift

Алан-э-Дейл       26.04.2022 г.

Введение в функциональное реактивное программирование

Зачем читать: чтобы узнать о новой парадигме программирования и попробовать её в Swift.

Где читать: на Flexiple.

Что такое функциональное реактивное программирование?

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

А что такое функциональное программирование?

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

И тогда в чём смысл реактивного программирования?

Это программирование с асинхронными потоками данных.

А что такое поток?

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

Под Swift написаны две классные библиотеки для реактивного программирования: RxSwift и RxCocoa. Первая более популярна, поэтому автор в основном говорит о ней.

Using the REPL

If you run the command without any other arguments,
you’ll launch the REPL, an interactive shell
that will read, evaluate, and print the results
of any Swift code you enter.

Interacting with the REPL is a great way to experiment with Swift.
For example, if you enter the expression ,
the result of the expression, , is printed on the next line:

You can assign values to constants and variables,
and use them in subsequent lines.
For instance, the value
can be assigned to the constant ,
and then passed as an argument to the function:

If you enter an invalid expression,
the REPL will print an error showing where the problem occurred:

You can use the up-arrow and down-arrow keys ( and )
to cycle through previous lines entered into the REPL.
This allows you to make a slight change to a previous expression
without retyping the entire line,
and is especially convenient for fixing errors like the one in the previous example:

Another useful feature of the REPL
is that it can automatically suggest functions and methods
that can be used in a particular context.
For example, if you enter
after a dot operator on a value
and then hit the tab key (),
the REPL will give a list of available completions
like and :

If you start a block of code,
such as when iterating over an array with a loop,
the REPL will automatically indent the next line,
and change the prompt character from to
to indicate that code entered on that line
will only be evaluated when the entire code block is evaluated.

All of the functionality of Swift is available to you from the REPL,
from writing control flow statements
to declaring and instantiating structures and classes.

You can also import any available system modules,
such as on macOS and on Linux:

On Windows

The REPL depends on Python bindings. You must ensure that Python is available
in the path. The following command adds Python to the PATH so that it can be
used:

Because the Windows installation separates out the SDK from the toolchain, a few
extra parameters must be passed to the REPL. This allows you to use multiple
different SDKs with the same toolchain.

Литералы

Литералы являются исходным кодом представления типа значения, например, цифры или строки.

Ниже приведены примеры литералов:

Литерал не имеет самостоятельный тип. Вместо этого, литерал обрабатывается как имеющий бесконечную точность и выводимый тип в Swift пытается вывести тип для литерала. Например, в объявлении let x: Int8 = 42, Swift использует явную аннотацию типа (: Int8) и делает вывод, что тип целочисленного литерала 42 будет Int8. Если не доступна информация о типе, Swift делает вывод, что тип литерала является одним из дефолтных типов литерала, определенных в стандартной библиотеке Swift. Дефолтные типы (или типы по умолчанию) являются Int для целочисленных литералов, Double для литералов с плавающей точкой, String для строковых литералов и Bool для логических литералов. Например, в объявлении let str = «Hello, world», дефолтный выведенный тип литерала строки «Hello, world» будет String.

Устанавливая тип аннотации для значения литерала, тип аннотации должен быть типом, экземпляр которого будет создан из этого значения литерала. То есть, тип должен соответствовать одному из следующих стандартных протоколов библиотеки Swift: ExpressibleByIntegerLiteral для целочисленных литералов, FloatingPointLiteralConvertible для литералов с плавающей точкой, StringLiteralConvertible для строковых литералов, и BooleanLiteralConvertible для булева литералов. Например, Int8 соответствует протоколу ExpressibleByIntegerLiteral, и поэтому может быть использован в аннотации типа для целочисленного литерала 42 в объявлении let x: Int8 = 42.

Disposing

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

Важно помнить, что Observable это «холодный» тип, то есть наш observable не «испускает» никаких событий, пока на него не подпишутся. Observable существует до тех пор, пока он не пошлет сообщение об ошибке (error) или сообщение о завершении (completed)

Если мы хотим явно отменить подписку, то можем сделать следующее.

Есть более красивый правильный вариант.

Таким образом мы добавляем нашу подписку в сумку утилизации или в DisposeBag.
Для чего это нужно? Если вы, используя подписку, не добавите ее в сумку или явно не вызовете dispose, ну или в крайнем случае не приведете каким-то образом observable к завершению, то скорее всего вы получите утечку памяти. DisposeBag вы будете использовать очень часто в своей работе с RxSwift.

Базовые типы и управление потоком в Swift

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

Float и Double

Давайте попробуем вставить еще пару строк в конец нашей игровой площадки и познакомимся с базовыми типами Float и Double:

Есть два типа для работы с числами с плавающей точкой: Float и Double:

  • Double — представляет собой 64-битное число с плавающей точкой. Используйте его когда число с плавающей точкой должно быть очень большим или чрезвычайно точным
  • Float — представляет собой 32-битное число с плавающей точкой. Используйте его, когда значение не нуждается в 64-битной точности.

Тип Double — более точный, чем Float и является типом по умолчанию. Это значит, что константа priceInferred, является так же типом Double. Поэтому, если мы хотим заменить тип Double на тип Float, мы должны написать следующее:

Bool

Вписываем себе пример констант логического типа Bool:

Обратите внимание, что логические значения в Swift имеют значения true или false, в отличии от YES/NO в Objective-C. Так же как с Int и Double, вам не нужно указывать константы или переменные как Bool, если при создании вы присвоили им значения true или false

Подобрались к строковым значениям:

Обратите внимание, что больше мы не используем символ @ как в Objective-C

Конструкции If и интерполяция строк

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

Так, в примере выше есть новая техника, называемая интерполяция строк. Если вы захотите вставить что-то в строку, что может быть заменено по значению, то вы должны использовать вот такой простой синтаксис: «\(ваше выражение)».

Вы можете наблюдать работу функции print() в боковой панели, но это может быть проблематично, если ваша строка длинная. Для того, чтобы увидеть результат полностью вам нужно нажать на пиктограмму глаза, в правой части playground’а, который появится при наведении на строку результата:

Есть и другой способ посмотреть длинное значение выражения. Вам нужно пройти в главное меню Xcode (то, что наверху) View\Assistant Editor\Show Assistant Editor.

Assistant Editor покажет вам результат работы функции print() без наведения на строку результата, что согласитесь, само по себе проще. Если вы что-то не поняли, то можете скачать наш файл playground’а со всем кодом что был написан выше.

Особенности профессии

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

Программист Swift должен:

  • создавать программы;
  • проведить тестирование программ;
  • размещять созданные продукты в магазине, анализировать жалобы и пожелания пользователей, которые используют приложение;
  • внесенить исправления;
  • создавать обновления, инструкции;
  • уметь оценивать бюджет и своё время.

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

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

Важно знание иностранного языка, навыки работы с устройствами компании Apple

Добавление и удаление

Для того, чтобы вставить символ в строку по указанному индексу, используйте insert(_:at:) метод, а для того, чтобы вставить содержимое другой строки по указанному индексу, используйте метод insert(contentsOf:at:).

Для того, чтобы удалить символ из строки по указанному индексу используйте remove(at:), если вы хотите удалить значения по указанному диапазону индексов, используйте метод removeSubrange(_:):

Заметка

Вы можете использовать методы insert(_:at:), insert(contentsOf:at:), remove(at:) и removeSubrange(_:) с любыми типами, которые соответствуют протоколу RangeReplaceableCollection. Это включает в себя String, как показано тут, а так же коллекции, такие как Array, Dictionary и Set.

Подстроки

Вы можете получить подстроку из строки, например, используя сабскрипт или метод типа и prefix(_:), результат которого возвращает экземпляр подстроки, а не другую строку. Подстроки в Swift имеют практически те же самые методы, что и строки, что означает, что вы можете работать с подстроками так же как и со строками. Однако, в отличие от строк, вы используете подстроки непродолжительное время, пока проводите какие-то манипуляции над строками. Когда вы готовы хранить результат более продолжительное время, то вы конвертируете подстроку в строку. Например:

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

В примере выше и greeting является строкой, которая имеет свою область памяти, где создающие ее символы хранятся. Так как и beginning, является подстрокой от greeting, то она переиспользует память. которую использует greeting. И наоборот, newString является строкой, которая была создана из подстроки и теперь она имеет свое хранилище. Рисунок ниже поможет нам разобраться с этими взаимоотношениями:

Заметка

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

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

Сравнения с другими языками

Swift считается языком программирования семейства C и во многом похож на C:

  • Большинство операторов C используются в Swift, но есть несколько новых операторов, например, для поддержки целочисленных операций с переполнением (см. Раздел «Различия»).
  • Фигурные скобки используются для группировки операторов.
  • Переменные назначаются с использованием знака равенства , но сравниваются с использованием двух последовательных знаков равенства . Новый оператор идентификации === используется для проверки того, относятся ли два элемента данных к одному и тому же объекту .
  • Управляющие операторы , и аналогичны, но имеют расширенные функции, например, a, который принимает нецелочисленные регистры и поддерживает сопоставление с образцом и условное разворачивание опций, использует синтаксис.
  • Квадратные скобки используются с массивами как для их объявления, так и для получения значения по заданному индексу в одном из них.

Он также имеет сходство с Objective-C:

  • Основные числовые типы ( )
  • Методы класса наследуются, как и методы экземпляра; в методах класса — это класс, для которого был вызван метод.
  • Похожий … синтаксис перечисления.

Отличия от Objective-C:

  • Операторы не обязательно должны заканчиваться точкой с запятой ( ), хотя они должны использоваться, чтобы разрешить более одного оператора в строке.
  • Нет файлов заголовков.
  • Использует вывод типа .
  • Общее программирование .
  • Функции — это первоклассные объекты.
  • С вариантами перечисления могут быть связаны данные ( алгебраические типы данных ).
  • Операторы могут быть переопределены для классов ( перегрузка операторов ), а также могут быть определены новые операторы.
  • Строки полностью поддерживают Unicode . Большинство символов Юникода можно использовать как в идентификаторах, так и в операторах.
  • Нет обработки исключений . Swift 2 представляет другую несовместимую модель обработки ошибок.
  • Некоторые особенности более ранних языков C-семейства , которыми легко злоупотреблять, были удалены:
    • По умолчанию указатели не отображаются. Программисту нет необходимости отслеживать и отмечать имена для ссылки или разыменования.
    • Назначения не возвращают значения. Это предотвращает распространенную ошибку записи вместо того , чтобы вызывать ошибку времени компиляции.
    • Нет необходимости использовать операторы в блоках. Отдельные случаи не переходят к следующему, если не используется оператор.
    • Переменные и константы всегда инициализируются, а границы массива всегда проверяются.
    • Целочисленные переполнения , которые приводят к неопределенному поведению для целых чисел со знаком в C, улавливаются как ошибка времени выполнения в Swift. Программисты могут выбрать , чтобы позволить переполняется, используя специальные арифметические операторы , , , и . Свойства и определены в Swift для всех целочисленных типов и могут использоваться для безопасной проверки потенциальных переполнений, вместо того, чтобы полагаться на константы, определенные для каждого типа во внешних библиотеках.
    • Форма и , состоящая из одного оператора , которая позволяет опускать фигурные скобки вокруг оператора, не поддерживается.
    • Перечисление в стиле C , которое часто приводит к ошибкам , не поддерживаются (начиная с Swift 3 и далее).
    • Операторы пре- и пост- инкремента и декремента ( , …) не поддерживаются (начиная с Swift 3 и далее), тем более что операторы в стиле C также не поддерживаются в Swift 3 и далее.

Кроме body

state — параметры

Property Wrapper
И еще одно замечание
Вы не сможете использовать события параметров структуры, обернутых в какие-то обертки. Компилятор позволяет вам написать этот код, но он просто не выполняется. Вероятно потому, что обертка — это и есть какой-то шаблонный код, выполняемый при наступлении этих событий.
update:
Оказывается, это был баг, наблюдатели свойства не срабатывали если значение модифицировалось не прямым присвоением, а как-то иначе. Например до версии XCode 11.5 вот этот код в одной ветке вызывал срабатывание willSet и didSet, а в другой ветке — нет.

В XCode 11.5 это пофиксили, и обзёрверы срабатывают корректно в обеих ветках кода.

State

Binding- параметры

И как всегда, личные грабли
Кстати, с Binding связан еще один интересный момент. Для родительской View любое изменение этой переменной вызывает повторную отрисовку всей дочерней View. Это означает уничтожение экземпляра дочерней View и создание новой на ее месте, с новым значением @Binding-переменной. Если вдруг, вы создали View в которой есть одновременно State и @Binding — подумайте, что произойдет с вашей State-переменной при изменении Binding. Скорее всего оно сбросится на значение по-умолчанию, или то, которое прописано в инициализаторе.
update: Как оказалось, SwiftUI умеет восстанавливать значения State переменных после повторной инициализации. Т.е. в описанном сценарии, после отработки init(), в котором вы сбросили значение этой State переменной на стартовое, SwiftUI всеравно достанет из кэша последнее значение, которое было до повторной инициализации и восстановит его. А вот с @ObservedObject такого не происходит, так что будьте аккуратнее.

Функциональные типы как типы параметров

Функциональные типы наподобие (Int, Int) -> Int могут быть типами параметров другой функции. Это позволяет определять некоторые аспекты реализации функции непосредственно во время ее вызова.

Следующий код печатает на экране результаты работы приведенных выше математических функций:

В этом примере объявлена функция printMathResult(_:_:_:), у которой есть три параметра. Первый параметр под названием mathFunction имеет тип (Int, Int) -> Int. Соответственно, аргументом этого параметра может быть любая функция такого же типа. Второй и третий параметры называются a и b и относятся к типу Int. Они служат для передачи двух входных значений для математической функции.

При вызове printMathResult(_:_:_:) получает в качестве входных данных функцию addTwoInts(_:_:) и два целочисленных значения 3 и 5. Затем она вызывает переданную функцию со значениями 3 и 5, а также выводит на экран результат 8.

Задача функции printMathResult(_:_:_:) заключается в том, чтобы печатать результат работы математической функции соответствующего типа. При этом конкретные детали этой математической функции не имеют значения – главное, чтобы она была подходящего типа. Все это позволяет безопасно управлять работой функции printMathResult(_:_:_:) непосредственно во время вызова.

Поехали!

Запустите Xcode и пройдите по File\New\Project. Выберите iOS\Application\Single View Application и нажмите Next.

В графе Product Name (имя приложения) напишите TipCalculator, установите Language на Swift и смените Devices на iPhone. Use Core Data выбирать не нужно. После, нажмите Next.

Выберите директорию для сохранения проекта и нажмите Create.

Давайте взглянем, что создал для нас Xcode: в верхнем левом углу выберите iPhone Simulator и нажмите кнопку Play.

Если вы все сделали правильно, то вы увидите симулятор с белым экраном:

Xcode создал одностраничное приложение с пустым белым экраном. Но не переживайте, в этом туториале вы его заполните!

Поехали!

Запустите Xcode и перейдите в: File \ New \ Playground. Введите название для проекта: «Instruments», затем выберите платформу «iOS» и нажмите «Далее». Выберите место для хранения вашего проекта и нажмите кнопку «Create». Когда откроется Playground, с вашим новым проектом, очистите его полностью, чтобы лишняя информация вам не мешала

Проектирование объектов объектно-ориентированным способом обычно начинается с самой концепции построения, затем распространяется уже на конкретные типы. Вы хотите создавать музыкальные инструменты, поэтому имеет смысл начинать с типа Instrument (тип Instrument будет общий для всех), а затем определять конкретные (не буквально!) инструменты, такие как пианино и гитары. Подумайте об этом как о генеалогическом дереве инструментов, где все течет от общего типа к конкретному сверху вниз. Пример:

Заметка

Для начала давайте обсудим следующее определения, они будут встречаться в статье, поэтому всегда можно будет вернуться в этот раздел, если вдруг вы забудете значение:is-a — public наследование.has-a — агрегирование (создается в классе).use-a — агрегирование (приходят извне, доступны не только в классе).

Связь между дочерним типом и его родительским типом является отношением is-a. То есть отношением объектов друг к другу, через наследование. Например, мы видим, что «Guitar is-a Instrument». То есть «Instrument» – это родитель, а «Guitar» по отношению к типу «Instrument» является дочерним типом – Гитара является наследником типа Инструмент. Теперь, когда у вас есть визуальное представление объектов, с которыми мы будем работать, можно начать реализацию нашего проекта.

Строковые литералы

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

Строковые литералы не могут содержать неэкранированные двойные кавычки («), неэкранированный обратный слеш (\), возврат каретки или перевод строки.

Многострочный строковый литерал заключен тремя двойными кавычками и выглядит следующим образом:

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

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

Многострочный строковый литерал может быть отступом, используя любую комбинацию пробелов и Tab-ов; этот отступ не входит в строку. Три кавычки — «»», которые завершают литерал, определяет отступ: каждая непустая строка в литерале должна начинаться с точно такого же отступа, который появляется перед закрытием «»». Вы можете добавить дополнительные пробелы после этого отступа.

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

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

Специальные символы могут быть включены в строковые литералы, используя следующие экранированные последовательные записи:

  • Нулевой символ (\0)
  • Обратный слеш (\\)
  • Горизонтальная табуляция (\t)
  • Перевод строки (\n)
  • Возврат каретки (\r)
  • Двойные кавычки (\»)
  • Одиночные кавычки (\’)
  • Скаляр Юникода (\u {n}), где n между первым и восьмым шестнадцатеричными символами

Значение выражения может быть вставлено в строку литерала, поместив выражение в скобки после обратного слеша (\). Интерполированное выражение может содержать строковый литерал, но не может содержать неэкранированный обратный слеш (\), возврат каретки или перевод строки.

Например, все следующие строковые литералы имеют одинаковое значение:

Строка, разделенная расширенными разделителями, представляет собой последовательность символов, заключенную в кавычки и в равное количество символов (#). Строка, разделенная расширенными разделителями, имеет следующий вид:

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

В следующем примере показан строковый литерал и строка, разделенная расширенными разделителями, которые создают эквивалентные строковые значения:

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

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

Дефолтный выводимый тип строчного литерала является String. Для получения дополнительной информации о типе String, см. Строки и символы и .

Строковые литералы, которые объединяются с оператором +, делают это во время компиляции. Например, значения textA и textB в примере ниже, являются идентичными, и объединения во время компиляции не происходит.

Дополнительные образовательные программы

Swift-разработчик – это серьезная профессия, которая требует немалого объема знаний и навыков. Самому обучиться если не невозможно, то крайне сложно. Поэтому спрос на онлайн-курсы, интенсивы и вебинары не падает.

Предлагаю рассмотреть еще парочку полезных онлайн-программ для новичков и специалистов-практиков.

Swift с полного нуля. Быстрый старт – Свифт Лаб

Swift с полного нуля. Быстрый старт – это обучающая программа, которая состоит из более 50 онлайн-занятий, посвященных Swift-разработке.

Продолжительность всех уроков в целом – 5,5 часов. Студентам предоставляется неограниченный доступ к учебным материалам.

Курс предназначен для начинающих без какого-либо опыта программирования, которые хотят узнать, как создать IT-продукт для iOS.

В программе:

  • работа с кортежами и опционалами;
  • массивы данных;
  • оператор guard;
  • замыкания;
  • основы языка;
  • преобразование типов;
  • псевдонимы типов;
  • кортежи;
  • операторы;
  • работа со строками;
  • переменные и константы;
  • множества;
  • циклы;
  • параметры и их виды;
  • замыкания.

Стоимость – 990 руб.

Еще несколько обучающих программ от Свифт Лаб:

  • iOS разработчик с нуля
  • SpriteKit. Создание 2D игр на Swift

Разработчик iOS – Swiftme.ru

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

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

Что входит в самостоятельный курс:

  • выдаются книги на русском языке о Swift-разработке и о самом языке;
  • предлагается более 350 тестов;
  • даются домашние практические задания, которых наберется около 170;
  • помощь наставников;
  • доступ в Telegram-чат и в Slack-чат.

Стоимость – от 600 руб.

Разработка и другие реализации

Поскольку язык является открытым, есть перспективы его переноса в Интернет. Некоторые веб — структуры уже разработаны, такие как IBM «s Kitura , Совершенный и Vapor .

Официальная рабочая группа «Серверные API-интерфейсы» также была создана Apple, в которой члены сообщества разработчиков Swift играют центральную роль.

Вторая свободная реализация Swift , что цели какао , Microsoft «s Common Language Infrastructure ( .NET ), а также Java и Android платформы существует как часть элементов компилятора от RemObjects программного обеспечения .

Комбинируя инструменты из LLVM и Macintosh Programmer’s Workshop , можно запустить очень небольшое подмножество языка в Mac OS 9 .

Собираем нейронку на Swift с помощью фреймворка Metal Shaders

Зачем читать: если вы интересуетесь нейросетями или вам интересен фреймворк Metal Performance Shaders.

Где читать: на Medium.

Евгений Стефанков — разработчик под iOS и лауреат Swift Student Challenge 2020 и 2021. Он уже давно интересуется нейронками — даже написал статью о том, как собрать нейросеть на Swift с нуля. В своей новой статье он показывает, как сделать ту же нейросеть быстрее с помощью фреймворка Metal Performance Shaders.

Это полноценный пошаговый гайд — весь процесс создания умной сетки разобран детально и скрупулёзно: от необучаемых слоёв до обучения и оценки. В конце Евгений скормил нейронке знаки хираганы — японской слоговой азбуки. Через 10 минут программа уже вовсю классифицировала японские символы — с точностью 75%. С цифрами она справилась ещё лучше — за те же 10 минут точность выросла до 98%.

Соединение вашего View Controller’а с вашей моделью

Уже почти все закончили. Все что осталось сделать, так это соединить ваш View Controller с вашей моделью.

Откройте ViewController.swift и добавьте свойство для модели вашего класса и метод для обновления пользовательского интерфейса:

Давайте пройдемся в refreshUI по одной строчке:

  1. В Swift вам нужно явно конвертировать один тип в другой. Здесь мы конвертируем tipCalc.total из Double в String
  2. Вы хотите, чтобы процент налога отображался как целое число (то есть от 0%-10%), чем дробное (что-то вроде 0.06). Так что просто умножим на 100.
  3. Помните, что это действие необходимо, так как свойство taxPctSlider.value является типом Float.
  4. Тут мы используем интерполяцию для обновления ярылка, отображающего процент налога.
  5. Очищаем результат в текстовом поле (text view) до тех пор пока пользователь не нажал кнопку Calculate.

Следующее, добавим вызов refreshUI внизу в viewDidLoad:

Так же имплементируем taxPercentageChanged и viewTapped:

taxPercentageChanged просто обращает «умножение на 100», в то время как viewTapped вызывает resignFirstResponder в поле totalTextField, когда пользователь нажал на view(что и заставляет клавиатуру исчезнуть с экрана).

Остался один метод. Имплементируем calculateTapped:

Давайте все разберем по порядку:

Заметка

Вот как это все работает, если вам это интересно.

Во время написания этого туториала класс String в Swift не имеет доступа ко всем методам, в отличии от NSString (NSString — класс в фреймворке Foundation). Если быть конкретным, то класс String в Swift не имеет метода, который бы преобразовывал тип String в тип Double, хотя NSSting такой метод имеет.

Вы можете вызвать (XXX as NSString)() в Swift для преобразования String в NSString. После чего вы можете использовать любой метод, доступный для NSString, например, метод, преобразующий String в Double.

  1. Тут нужно преобразовать тип String в Double. Это несколько коряво так делать, но думаем, уже скоро будет способ поприличнее.
  2. Здесь вы вызываете метод returnPossibleTips модели tipCalc, которая возвращает словарь с возможными процентами чаевых.
  3. Это то, как вы перебираете словарь через ключи и значения одновременно. Удобно, не так ли?
  4. Здесь мы используем интерполяцию строк, для создания строки, которую поместим в текстовое поле. Мы используем \n для начала новой строки.
  5. Наконец, мы присваиваем текстовому полю значение result.

Вот и все! Запускайте и наслаждайтесь вашим калькулятором чаевых!

Это конечный вариант нашего Xcode проекта.

Гость форума
От: admin

Эта тема закрыта для публикации ответов.