Изучаем Swift

В июне на WWDC 2014 Apple объявила о новом языке программирования Swift для создания приложений для OS  X и iOS.

Swift является статически типизованным (statically typed) языком, что означает, что мы не можем больше бессистемно забрасывать объекты в типизованные переменные и заставлять компилятор доверять нам, что этот объект именно этого типа. В Swift компилятор делает проверку типов и тем самым предохраняет нас от случайных runtime ошибок. Поэтому Apple декларирует Swift как язык безопасного программирования.

В Swift очень много интересных современных новшеств: Optionals, Generics, Type Inference, элементы функционального программирования, новые возможности структур, перечислений, классов, Playgrounds и т.д.

В Swift обеспечено тесное взаимодействие c Objective-C и, следовательно, доступ к возможностям Cocoa при разработке приложений для OS X и iOS.

Все это хочется попробовать. Сейчас в мире миллионы разработчиков, изучающих Swift. Они предлагают различные блоги и  курсы обучения (как Video, так и обычные) в основном на английском языке. Но у каждого своя кривая изучения в зависимости от опыта и интересов. Я предлагаю свою: я буду размещать переводы на русский язык наиболее интересных и фундаментальных статей по Swift и iOS 8. Кроме того, я буду испытывать наиболее интересные предложения на своих примерах и размещать их в  Github.

I. Парсинг JSON данных

Первая тема, с которой столкнулись разработчики  Swift, – это разбор (парсинг) JSON – данных. Надо преобразовать JSON-данные, полученные по сети, в объектную модель. Сложность решения задачи связана с тем, что Swift является статически типизованным и для такого гибкого формата как JSON потребуется цепочка проверок и приведений типов для получения нужного значения. В результате код на Swift оказывается неуклюжим и некрасивым. Было предложено много решений, но самыми изящными, легкими и универсальными оказались решения, основанные на новом понятии Optionals и функциональном программировании ( которое пусть частично, но реализовано в Swift ).Такие концепции функционального программирования как  Monads, Applicative Functors, и Currying помогают сделать код для JSON  парсинга кратким.

Основная идея применения функционального программирования к парсингу приводится в статье “Работа с JSON в Swift. Безопасно и просто.” (перевод) – оригинал Chris Eidhof  “Parsing JSON in Swift. Safe and easy”

Более подробно свою идею Крис изложил на выступлении в San Francisco “Функциональное программирование в Swift на примере JSON” (перевод).

Парсинг JSON оказался очень благодарной темой для применения таких новых инструментов Swift, как generics (дженерики),custom operators  (пользовательские операторы), overloading (“перегрузка”) функций и использование type inference (так называемые “подразумеваемые” типы, то есть логически выводимые из контекста). Все это приводит к великолепным результатам, представленным в статьях Tony DiPasquale, : красивому, хорошо читаемому и очень краткому коду. Но к сожалению, на сложных вложенных структурах JSON его алгоритм выходит на предельные возможности компилятора Swift (что тоже интересно) и построение исполняемого кода растягивается на минуты. Тогда он предлагает выход из положения, основанный на использовании перечислений, enum, возможности которых в Swift очень значительны.

Tony DiPasquale написал целую серию статей и создал библиотеку для парсинга JSON в Swift с именем Argo. Он очень подробно описывает логику последовательных преобразований модели, способной “вытащить” из JSON свои данные: от конструкций if-let до infix– пользовательских операторов, использования дженериков (Generics) и type inference, то есть “логически выводимых из контекста” типов данных. Иногда его решения приводят к парадоксальным решениям: без единого намека на тип данных, все  обрабатывается правильно. Это похоже на чудо. За это приходится платить слишком медленной компиляцией сложных, вложенных структур JSON. Поэтому библиотек Argo на самом деле две: вторая тоже Argo, которая более практична с точки зрения быстродействия компиляции для сложных вложенных структур. Надеюсь, это временные трудности молодого языка программирования Swift.  Вот статьи Tony DiPasquale:

 “Эффективный JSON c функциональными концепциями и дженериками в Swift.” (перевод) – оригинал “Efficient JSON in Swift with Functional Concepts and Generics”.

“Реальный мир парсинга JSON.” (перевод) – оригинал “Real World JSON Parsing with Swift.”

“Парсинг вложенных JSON и массивов в Swift.” (перевод) – оригинал “Parsing Embedded JSON and Arrays in Swift.”

Я провела проверку  идей, изложенных в этих материалах, на двух типах тестовых данных. Первый тип тестовых данных приведен в статье Chris Eidhof  “Parsing JSON in Swift. Safe and easy” и представляет собой массив из двух блогов:

// Данные как в статье Cris Eidnof
                  <a href="http://chris.eidhof.nl/posts/json-parsing-in-swift.html"> http://chris.eidhof.nl/posts/json-parsing-in-swift.html</a>

 [
  "stat": "ok",
  "blogs": [
    "blog": [
      [
        "id" : 73,
        "name" : "Bloxus test",
        "needspassword" : true,
        "url" : "http://remote.bloxus.com/"
      ],
      [
        "id" : 74,
        "name" : "Manila Test",
        "needspassword" : false,
        "url" : "http://flickrtest1.userland.com/"
      ]
    ]
  ]
]

Второй тип тестовых данных находится на Flickr.com и представляет собой данные в формате JSON  о 100 топ местах, в которых сделаны фотографии, размещенные на Flickr.com:

{
    places =     {
        "date_start" = 1414108800;
        "date_stop" = 1414195199;
        place =         (
                        {
                "_content" = "London, England, United Kingdom";
                latitude = "51.506";
                longitude = "-0.127";
                "photo_count" = 1661;
                "place_id" = "hP_s5s9VVr5Qcg";
                "place_type" = locality;
                "place_type_id" = 7;
                "place_url" = "/United+Kingdom/England/London";
                timezone = "Europe/London";
                "woe_name" = London;
                woeid = 44418;
            },
                        {
                "_content" = "Sao Paulo, SP, Brazil";
                latitude = "-23.562";
                longitude = "-46.654";
                "photo_count" = 119;
                "place_id" = 0RylrWxVV79p49E;
                "place_type" = locality;
                "place_type_id" = 7;
                "place_url" = "/Brazil/Sao+Paulo/S%C3%A3o+Paulo/in-S%C3%A3o+Paulo";
                timezone = "America/Sao_Paulo";
                "woe_name" = "Sao Paulo";
                woeid = 455827;
            },
..........................

Для считывания данных с Flickr.com использовался Flickr API, представленный в курсе Стэнфордского Университета “Stanford CS 193P iOS 7”, написанный на Objective-C, так что попутно нам пришлось осуществить доступ к Objective-C классам из Swift.

Результаты тестов алгоритмов Криса ( Chris Eidhof ) представлены в посте “Swift код к статьям автора Chris Eidhof.” и на Github.

Результаты тестов алгоритмов Тони ( Tony DiPasquale ) представлены в постах

 “Swift код к статье Tony DePasquale “Эффективный JSON с функциональными концепциями и дженериками в Swift””,

 “Swift код к статье Tony DePasquale “Реальный мир парсинга JSON””,

“Swift код к статье Tony DePasquale “Парсинг вложенных JSON и массивов в Swift”

и на Github. Отдельно тестировалась библиотека ARGO парсинга JSON на Swift.

Одной из основополагающих концепций функционального программирования является  непростое понятие “монада”. ALEXANDROS SALAZAR в серии статей, приведенных ниже, очень  интересно объясняет, как происходит “Управления ошибками и Optionals в Swift”, что такое “Optional chaining” и “Implicitly Unwrapped Optionals”, и через эти понятия осторожно подкрадывается к объяснению такого непростого понятия как монада и каковы ее свойства. Основываясь на опыте применения уже существующих языков функционального программирования Haskell и Scala, он пытается предсказать будущее Swift в части наполнения его более мощными конструкциями функционального программирования. Вот его статьи:

  1. “Управление ошибками в Swift: магия и могущество.” (перевод) – оригинал “Error Handling in Swift: Might and Magic
  2.  “Управление ошибками в Swift: магия и могущество -2” (перевод) – оригинал “Error Handling in Swift: Might and Magic – Part II”
  3. “Понимание Optional Chaining” (перевод) – оригинал “Understanding Optional Chaining”
  4. “Подробнее об Implicitly Unwrapped Optionals ( IUO )” (перевод) – оригинал  “Implicitly Unwrapped Optionals in Depth.”
  5. “Кульминация – часть 1” (перевод) – оригинал “The Culmination : Part I”
  6. “Кульминация – часть 2” (перевод) – оригинал “The Culmination : Part II”
  7. “Кульминация – финальная часть “ (перевод) – оригинал “The Culmination : Final Part”

Код, иллюстрирующий идеи первых 4-х статей представлен в посте  “Управление ошибками и Optionals в Swift – интерпретация в коде.”

На эту тему есть еще ряд очень интересных статей, которые ждут своего перевода и тестирования:
“Исполнение “функциональных желаний” (еще один пост на тему “Как парсить JSON  в Swift) – Rob Naper Functional Wish Fulfillment (another of those “how to parse JSON in Swift” blog posts )
Swift JSON Redux Part 1
Swift JSON Redux Part 2 
Flat Map 
Rob Naper Flattenin ‘Your Mappenin’
JSONHelper

Очень полезный материал Managing optionals in Swift.swift

II. Функции

Очень хорошие статьи

The Many Faces of Swift Functions
Facets of Swift, Part 4: Functions
Implicitly converting functions to return optionals
Generic Functions in Swift
Swift Function Currying 
Which function does Swift call? Part 4: Generics

 

Leave a Reply

Your email address will not be published. Required fields are marked *