Привет!

Сегодня мы собираемся разработать проект, используя возможности объектно-ориентированной парадигмы языка. В Swift реализована классическая однородительская модель наследования и возможность реализовать несколько интерфейсов поведения при помощи протоколов. Очень важная, одна из «убойных» фич Swift — это функция Nil-safety. Эта система делит все типы на две части — nil и not nil, и добавляет несколько операторов для взаимодействия со значениями nil типа. Эта функция позволяет писать nil-безопасный код и практически избегать исключений, связанных с использованных пустых объектов.

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

  • Структуры
  • Расширения

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

Темы:

  • ООП, классы, протоколы, файлы, getter/setter
  • Nilable переменные
  • Расширения
  • Ошибки

Совет! Продолжайте читать официальную документацию и статьи о преимуществах Swift. Также, если понадобится, найдите больше информации о принципах ООП, ООП в Swift и посмотрите примеры перед началом работы с заданием.

Документация Swift

Проект: Служба спасения

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

Совет! Если вы читали что-нибудь об ООП в Swift, вы уже знакомы с объектом structure и его преимуществами. Это очень популярная конструкция для описания моделей данных, вы должны использовать ее для «модельных» классов (с данными) в наших проектах.

Задания

Требование! Создайте исполняемый пакет и реализуйте решения в нём. Для его создания необходимо вызвать команду swift package init --type executable --name Day01 внутри директории src. Более подробное описание о создании проектов можно прочитать в документации.

Задание 1. Служба спасения

Определите, находится ли инцидент в заданной зоне.

Описание инцидента:

  • Инцидент описывается при помощи двух целочисленных координат на координатной плоскости
  • Инцидент имеет:
    • Описание
    • Номер заявителя - может быть nil
    • Поле, описывающее один из трех типов инцидента (например, fire, gas leak, cat on the tree) - может быть nil

Требование! Как было сказано ранее, используйте структуры для описания модели данных в этом и последующих заданиях. Совет! Используйте Enum для перечисления типов, например - типы инцидентов

Описание зоны:

  • Зона имеет четырехугольную, треугольную или круглую форму, представляющую фигуры на координатной плоскости.
  • Зона наследуется от общей службы спасения, которая имеет общий номер (с кодом оператора 800)
  • Каждая зона имеет:
    • Номер телефона
    • Имя
    • Код службы департамента
    • Уровень, представляющий вероятность инцидента (низкий, средний, высокий)
  • Зона имеет метод, чтобы определить, произошел ли в ней инцидент.

Входные данные:

  • Все координаты вводятся в формате двух целочисленных значений разделенных ';'. Например: 5;4.
  • Ввод параметров зоны: программа автоматически определяет форму зоны, исходя из введенных данных:
    • Для окружности - два значения, введенных и разделенных пробелом: ее центр и радиус. Например: 5;4 6
    • Для треугольной - три точки, разделенных пробелами. Например, 5;4 3;6 2;5
    • Для четырехугольной - четыре точки, разделенных пробелами. Например: 5;4 3;6 2;5 5;9
  • Остальная информация о зонах, для легкого использования, должна быть записана в коде
  • Ввод точек с координатами инцидента
  • Неправильные введенные данные вызывают ошибку

Выходные данные:

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

Пример Входные данные

Enter zone parameters:
3;4 2

The zone info:
  The shape of area: circle 
  Phone number: 89347362826
  Name: Sovetsky district
  Emergency dept: 49324
  Danger level: low 

Enter an incident coordinates:
9;9

The incident info:
  Description: the woman said her cat can't get off the tree
  Phone number: +74832648573
  Type: cat on the tree

Выходные данные

An incident is not in Sovetsky district
Switch the applicant to the common number: 88008473824

Задание 2. Маскирование номера

Маска телефона — это полезная функция UX, которая улучшает читаемость телефонных номеров.
Напишите расширение класса String, которое применяет две разные маски к номеру телефона:

  • Он работает с 11-значными числами, начинающимися с 7 или 8, или с 12-значными числами, начинающимися с +7:
    • Если код оператора 800, то номер преобразуется в вид «8 (800) xxx xx xx»
    • Для другого оператора маска "+7 xxx xxx-xx-xx"
    • Обратите внимание, что помимо скобок, пробелов и дефисов, первая цифра (страна) также меняется в зависимости от маски. Пример: 84352835724 преобразуется в +7 435 283-57-24.
  • Остальные номера игнорируются

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

Входные данные Выходные данные
88005553535 8 (800) 555 35 35
89152342343 +7 915 234-23-43

Задание 3. Обработка ответов сервера

Предположим, что у нас есть сервер для нашего приложения, и он возвращает ответ на наши запросы. Ответ содержит код и сообщение. Существует множество различных кодов ответов — проверьте описание кодов HTTP.

В нашем приложении по коду ответ можно разделить на два типа: Success и Error. Это распространенный случай, когда можно использовать enum. Реализуйте эту логику с его помощь:

  • Success, если код 200 или 201. Подтип должен иметь сообщение - string "The request processed successfully"
  • Error, если код 400 и более. Сообщение - JSON с заголовком и описанием ошибки.

Также с сервера могут быть разными. Приложение должно иметь подтипы ошибок в зависимости от кода. Например:

  • Существует 4 известных типа ошибок (1000-1003). Они имеют заголовок и описание(придумайте его):
    • 1000, "The user is not identified", description
    • 1001, "The session is expired", description
    • 1002, "No connection", description
    • 1003, "The device has failed the verification", description
  • Остальные коды ответов (отличные от 200, 201, 1000-1003) обрабатываются с общим типом Unknown, который имеет заголовок "Error code: $code" и описание "Unknown error. Please, try again later"

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

Входные данные: код сервера, введенный при помощи консоли Выходные данные: программа выводит тип ответа (если Error, то конкретный тип ошибки) и его информацию: код and сообщение for Success or код, заголовок and и описание for Error

Входные данные Выходные данные
1003 NoConnectionError:
  Code: 1003
  Title: No connection
  Descriprion: There is no internet connection. Try later.

Бонусное задание 4. Неожиданности повсюду

Описать объект города. Город должен иметь:

  • Имя
  • Коллекцию с различными зонами (для простоты может быть записано в коде)

Определите, в какой зоне произошел инцидент на примере одного города. Если точка инцидента попадает между зонами, программа переключает ее на отделение из ближайшей зоны.

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

Данные зон Для примера в том же формате, как и задании 1 выделим координаты зон города Novosibirsk: Sovetsky district - (7;7 1), Kalinisky district - (11;11 12;12 12;11), Kirovsky district - (0;0 0;-2 -2;0 -1;1).

Пример: Входные данные

Enter an incident coordinates:
9;9

Выходные данные

The city info:
  Name: Novosibirsk 
  The common number: 8 (800) 847 38 24

The incident info:
  Description: the woman said her cat can't get off the tree
  Phone number: +7 934 736-28-26
  Type: cat on the tree

The incident didn't match with any zone. The nearest zone: Sovetsky district
The zone info:
  The shape of area: circle 
  Phone number: +7 934 736-28-26
  Name: Sovetsky district
  Emergency dept: 49324
  Danger level: low