Swift, Playgrounds и XCPlayground

Перевод статьи “Swift, Playgrounds, and XCPlayground”.
Swift Playgrounds – это интересный инструмент в Xcode 6, позволяющий создавать единственный файл для тестирования кода перед тем, как поместить тестируемый код в основное приложение. До появления Playgrounds, у вас было две возможности — создать новое git ответвление от master ветки приложения, над которым вы работаете, или, как делаю я, открыть новый проект с шаблоном Single View Application и попытаться построить некоторую базу для тестирования того, что вы хотите.
Playgrounds уменьшают суммарное количество шагов между идеей и созданием  прототипа, но есть определенные вещи, которые нельзя выполнить на Playground как она есть, то есть ничего не добавляя. Например, запрос данных с сервера или показ views, нарисованных с помощью класса UIViews.
К счастью, эти возможности требуют всего лишь импорта одного модуля.

XCPlayground

XCPlayground – это новый модуль, у которого есть несколько методов, позволяющих получить максимум возможного от Playgrounds. Добавление его к вашему Playground – это простое добавление import предложения прямо сразу за предложением import UIKit, которое появляется по умолчанию:

import UIKit // это появляется по умолчанию
import XCPlayground // это мы добавляем

Выполнение XCP должно продолжаться бесконечно

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

Continue reading

Многоликие функции Swift

Русский перевод статьи Natasha Murashev The Many Faces of Swift Functions.

Хотя у Objective-C синтаксис выглядит несколько странно,  по сравнению с другими языками программирования, синтаксис метода – прост и понятен. Вот небольшой экскурс в прошлое

+ (void)mySimpleMethod
{
    // метод "класса"
    // нет параметров
    // нет возвращаемых значений
}

- (NSString *)myMethodNameWithParameter1:(NSString *)param1 parameter2:(NSNumber *)param2
{
    // метод "экземпляра"
    // один параметр - типа NSString указатель,
    // второй параметр - типа NSNumber указатель
    // должен вернуть значение типа NSString указатель
    return @"hello, world!";
}

В противоположность этому, синтаксис  Swift выглядит в большинстве случаев также, как и в других языках программирования, но временами он может быть более сложным и запутанным, чем Objective-C.

Continue reading

Какие функции вызывает Swift? Часть 5: Range против Interval.

Это русский перевод статьи airspeedvelocity Which function does Swift call? Part 5: Range vs Interval

Это часть 5 из серии постов о том, как Swift разрешает “неоднозначность” в “перегруженных” функциях. Часть 1 можно найти  здесь (русский перевод – здесь). В предыдущей статье (русский перевод – здесь), мы рассматривали как управлять  generics.

И наконец …

Теперь, когда мы рассмотрели как подбираются  generics, мы можем наконец ответить на первоначальный вопрос – как мы получаем тип  Range по умолчанию для выражения 1...5 ? Вот образец кода:

// r будет иметь тип Range<Int>
let r = 1...5

// если вы хотите такой тип ClosedInterval<Int>, то вам
// нужно задать тип явно:
let integer_interval: ClosedInterval = 1...5

// если вам нужен тип Doubles, то нет необходимости
// декларировать тип явно.
// floatingpoint_interval is a ClosedInterval<Double>
let floatingpoint_interval = 1.0...5.0

Функция, соответствующая infix оператору  ...  , определяется трижды в стандартной библиотеке со следующими сигнатурами:

func ...<T : Comparable>
  (start: T, end: T) -> ClosedInterval<T>

func ...<Pos : ForwardIndexType>
  (minimum: Pos, maximum: Pos) -> Range<Pos>

func ...<Pos : ForwardIndexType where Pos : Comparable>;
  (start: Pos, end: Pos) -> Range<Pos>

Первые две – очень простые. Они обе generic, у них единственная generic метка-заполнитель (placeholder), которая ограничена единственным протоколом. Нет преимущества у одного ограничения перед другим.

Оба протокола Comparable и ForwardIndexType происходят из протокола Equatable, но ни один из них не происходит от другого. Если мы оставим только эти две функции, то мы получим ошибку “неоднозначности” –ambiguous call error.

Но есть третья функция, которая и заставляет Swift выбрать Range , а не  ClosedInterval. В этой функции, Pos ограничивается не только ForwardIndexType, но и Comparable. Ограничение двумя протоколами выигрывает у ограничения с одним, так что при “перегрузке” будет выбрана эта функция.

Continue reading

Какие функции вызывает Swift? Часть 4: Generics.

Это русский перевод статьи airspeedvelocity “Which function does Swift call? Part 4: Generics”.

Это 4 часть из серии статей, посвященных тому, как выбираются “перегруженные” (overloaded) функции в Swift. Часть 1 рассматривает “перегрузку” (overloading) по типу возвращаемого значения, часть 2 о том, как различные функции с простым одним аргументом выбираются по принципу “наиболее подходящей” функции, и часть 3 раскрывает этот принцип более детально в плане протоколов.

Мы начали серию статей с вопроса, почему мы получаем тип Range для 1…5 вместо типа  ClosedInterval? Сегодня мы разберем как  generics вписываются в иерархию “наиболее подходящей” функции, и у нас наконец будет достаточно информации для ответа на вопрос.

Generics – это более низкий приоритет

Continue reading

Какие функции вызывает Swift? Часть 3: Композиция протоколов.

Это русский перевод статьи airspeedvelocity “Which functions does Swift call? Part 3: Protocol Composion”

В предыдущих статьях мы исследовали,  как функции Swift могут быть “перегружены” только по возвращаемому типу, и как Swift выбирает между различными возможными “перегрузками” с помощью механизма “наилучшего соответствия” ( best-match mechanism).

Эти исследования мы провели с целью выяснения причины, почему  1…5 возвращает тип Range а не тип ClosedInterval. И для понимания этого нам нужно рассмотреть как generics работают с критериями “наилучшего соответствия”.

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

Протоколы могут объединяться путем расположения 0 или более протоколов между угловыми скобками в предложении  protocol<> . Книга Apple Swift говорит следующее:

ЗАМЕЧАНИЕ
Композиция протоколов не определяет новый , постоянный тип протокола. А определяет временный локальный протокол,  у которого есть комбинированнык требования всех протоколов в композиции.

Читая это, можно подумать, что декларирование протокола protocol<P,Q> подобно декларированию анонимного протокола Tmp: P, Q { }, и Tmp можно использовать не давая ему имени. Но означает это не совсем то, и способ, который бы высветил разницу состоит в декларировании функций, которые имеют аргументы, декларированные с протоколом.

Continue reading

Какие функции вызывает Swift? Часть 2: Единственные аргументы.

Это русский перевод статьи airspeedvelocity 

Which function does Swift call? Part 2: Single Arguments

В предыдущей статье мы видели, что Swift разрешает “перегрузку” ( overloading ) функций просто по типу возвращаемого значения. С такого типа “перегрузками” явное объявление типа говорит Swift какую функцию вы хотите вызвать:

// r будет иметь тип Range<Int>
let r = 1...5

// если вы хотите тип ClosedInterval<Int>, вам следует
// явно указать:
let integer_interval: ClosedInterval = 1...5

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

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

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

Если Swift не находит функцию, которая имеет точно такой же тип, как мы передали при вызове, следующей предпочтительной опцией является наследуемый класс или протокол. Классы -“дети” или протоколы являются более предпочтительными чем “родители”.

Давайте посмотрим это в действии:

Continue reading

Какие функции вызывает Swift? Часть 1: Возвращаемые значения

Это русский перевод статьи airspeedvelocity

“Which function does Swift call? Part 1: Return Values “.

Тип данных ClosedInterval “стесняется”. Вам придется уговаривать его выйти из-за спины своего друга, Range.

// r будет иметь тип Range<Int>
let r = 1...5

// если вам нужен тип ClosedInterval<Int>, вам
// следует определить его явно:
let integer_interval: ClosedInterval = 1...5

// Но если вам нужен doubles, то нет необходимости
// декларировать его явно.
// floatingpoint_interval is a ClosedInterval<Double>
let floatingpoint_interval = 1.0...5.0

Начиная с  Swift 1.0 beta 5, Range поддерживается исключительно для представления диапазонов индексов в коллекции.

Если вы не работаете с индексами, тип ClosedInterval, возможно, это то, что вам нужно. У него есть методы, подобные contains, которые за фиксированное ( независящее от длины интервала ) время определяют, содержит ли интервал некоторое значение:

Continue reading

Swift код к статье “Парсинг вложенных JSON и массивов (Arrays) в Swift.”

В этом посте представлен Swift код, который сопровождал изучение и перевод статьи Tony DiPasquale  “Парсинг вложенных JSON  и массивов (Arrays) в Swift.” (перевод) – оригинал Parsing Embedded JSON and Arrays in Swift

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

Кроме того, хотелось бы отследить сам процесс превращения функции парсинга JSON-данных в Модель из тривиального  варианта в компактный  вариант “функциональных концепций”. В этой статье появление компактного варианта осложняется необходимостью доставать данные из “вложенных” JSON  структур и массивов. Посмотрим как эта задача решается с позиции Swift кода как на тестовых примерах, предложенных в самой статье, так и на двух наших контрольных данных.

Continue reading

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

В этом посте представлен Swift код, который сопровождал изучение и перевод статьи Tony DiPasquale  “Реальный мир парсинга JSON в Swift” (перевод) – оригинал Real World JSON Parsing with Swift .

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

Эксперименты с алгоритмами Тони ДеПаскуале проводились в Swift 1.1, и представлены в репозитории на Github, который включает в себя различные  Playground файлы и полноценное небольшое приложение для работы  с данными с сайта Flickr.com.

Continue reading

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

В этом посте представлен Swift код, который сопровождал изучение и перевод статей Tony DiPasquale . Статьи переведены на русский и представлены на этом сайте.

Вот эти статьи:

  1. “Эффективный JSON с функциональными концепциями и дженериками в Swift”  (перевод) – оригинал  Efficient JSON in Swift with Functional Concepts and Generics. Код Swift, сопровождающий изучение этой статьи , представлен в этом посте.
  2.  “Реальный мир парсинга JSON в Swift” (перевод) – оригинал Real World JSON Parsing with Swift . Код Swift, сопровождающий изучение этой статьи , представлен в этом посте.
  3. “Парсинг вложенных JSON  и массивов (Arrays) в Swift.” (перевод) – оригинал Parsing Embedded JSON and Arrays in Swift.  . Код Swift, сопровождающий изучение этой статьи , представлен в этом посте.

Автор предлагает Swift код в самих статьях, но это, как правило, только результирующий вариант с очень малым количеством примеров. Кроме того, хотелось отследить сам процесс превращения функции парсинга JSON-данных в Модель из тривиального и громоздкого "if-let" варианта в компактный  вариант “функциональных концепций”. Последний вариант представлен в виде цепочки трансформаций, начинающихся с запроса в “сеть” и заканчивающихся заполнением Модели данными. Он выдает на выходе не просто Модель, а Result <Модель>, включающий в себя помимо самой Модели, всевозможные ошибки на различных этапах трансформации.

Хотелось более рельефно увидеть как справляется вариант “функциональных концепций” с этими ошибками, потому что иногда в  статьях с целью краткости и простоты изложения приводится лишь набросок кода, иллюстрирующий ту или иную идею. Он не всегда компилируется в Swift. Кроме того Swift – еще молодой язык и имеет некоторые ошибки, о которых известно, и которые в дальнейшем будут устранены. Но сейчас, чтобы сделать код работающим, требуются некоторые дополнительные усилия.

Эксперименты с алгоритмами Тони ДеПаскуале проводились в Swift 1.1, и представлены в репозитории на Github, который включает в себя различные  Playground файлы и полноценное небольшое приложение для работы с данными с сайта Flickr.com.

Continue reading