11 заметок с тегом

Swift

Moscow Coding School

Прошлые курсы по айос-разработке в школе MCS были в зимой. Я иногда встречаю наших студентов, и расспрашиваю об успехах. Это интересно.

Один из студентов сменил профессию и теперь работает джуниор-разработчиком в известной московской компании. И ему это нравится. На зимнем интенсиве была тема про VIPER — и вот! — привет, Егор и ребята ;)

Зимний интенсив, кстати, был уникальным: он занимал все январские праздничные выходные. Мне кажется, там были только самые супер-мотивированные студенты!

Другой студент пришел на курс с идеей системной айос-клавиатуры с особенным, аккуратным оформлением и поведением (дизайном). После курса он сделал-таки свою клавиатуру. А потом запускал разные парсеры и пауки для обхода сайтов. На Свифте, разумеется.

Moscow Coding School приносит пользу. По этому поводу — анонс моего нового курса по айос-разработке на Свифте для новичков: moscoding.ru/swift/

Для анонса на сайте меня попросили написать краткое био. Пришлось вспомнить всякие интересные факты:

Первую программу для Мака написал в 11 лет на точном советском клоне компьютера Apple II. В университете изучал программирование микропроцессоров. Программировал Айфоны еще при Джобсе. Использую Свифт в продакшене.

Люблю работать в стартапах: Рокетбанк, Luuk, Paste. Сейчас занимаюсь независимой разработкой и консультирую программистов со всего мира по языкам Си, Обджектив-Си и Свифт. Участвую в Московском сообществе CocoaHeads Moscow.

Не свидетель секты запрета goto и #define. Считаю, что нельзя из #define делать новый язык, а из goto — макаронный код. Все остальное можно. Также увлекаюсь «рельсами», Ардуино и сноубордингом.

2016   edu   Swift

iOS 9 marked difference

We are familiar and well know all Swift changes between 2.0 and 2.1. And also difference between Xcode 6 and 7. But there are some changes between iOS 8 and 9.1 that we can’t ignore. Because... apps became malfunctioned.

CanOpenURL

Most significant and despicable difference is between iOS 9 and 9.1. The canOpenURL does not work as expected anymore. All checks for that are failing at this time.

if app.canOpenURL(url) {
   app.openURL(url)
}

To understand what happened, see this post: Quick Take on iOS 9 URL Scheme Changes.

But TL;DR is that you must explicitly set an array of URL schemes that your app may open. So add a key called LSApplicationQueriesSchemes to your Info.plist. And the value of this key is an array of URL schemes you want to be opened. Like: twitter, fb, instagram, vk.

More generally, xml for this in Info.plist should look like:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>twitter</string>
    <string>instagram</string>
    <string>comgooglemaps</string>
    <string>yandexnavi</string>
</array>

3D Touch

Next big thing is how to fast implement quick actions for 3D-touching app icon.

As I have no 3D Touch devices (have just Force Touch one) and have no expertise in there, I just provide a link where it described very well: Add 3D Touch quick actions tutorial.

See also:

Let’s code!

@autoclosure

Решил познакомиться с test-driven development. И, заодно, разобраться с XCTest Framework. Там много всего интересного, оказывается.

Например, Эпл пишет: Test-driven development is a first-class workflow within Xcode. То есть, в Икскоде четко соблюдается философия TDD, сформулированная Кентом Беком: те же утверждения, сравнения и т. д.

В Свифте для проверки утверждений тестирования используются примерно такие методы:

func XCTAssert(expression: @autoclosure () -> Bool, message: String, ...)

@autoclosure, которое я перевел как автозамыкание, — очень интересная штука. (В ранних бетах Икскоды-6 называлась @auto_closure.) Автозамыкание принимает ноль аргументов, и возвращает что угодно.

Если обычно замыкания в Свифте вызвываются так:

someFunc(doLater: (x: 2, y: 12, z: 85) -> Bool {
  // some code
}, lastPart: "06")

То автозамыкания — так:

someFunc(doLater(), lastPart: "0")

Применительно к ассертам в юнит-тестах, соответственно, так:

XCTAssert(colorMatch(), "rgb hex does not work")

Все красиво и ненавязчиво :) Что же нам еще почитать об этом?

Про автозамыкания:

Про юнит-тестирование:

2015   code   Swift   testing   Xcode

Swift Array Subrange: Slice

В работе над одним интересным проектом мне понадобились разные подмножества элементов одного массива. Для этого у массивов в Свифте есть метод subscript, в который кроме конкретного индекса можно передавать диапазон значений.

let deliciousDuck = rotissomat[2]
let anyOtherDucks = rotissomat[12...85]

В действительности же, это два разных метода:

subscript (index: Int) -> T
subscript (subRange: Range<Int>) -> Slice<T>

Метод, который принимает диапазон, возвращает подмножество данных типа Slice. Например:

let range: Range<Int> = 1..<3 // 2 elements

let ducks:   Array<String> = ["Huey", "Dewey", "Louie"]
let lastTwo: Slice<String> = ducks[range]

В документации Свифта уточняется, что Slice всегда использует область памяти, «смежную» с исходным массивом, и не бриджится в Обджектив-Си.

(Что такое ротиссомат? :-)

2015   code   Objective-C   Swift

Size Classes

В конце августа, на ежемесячной встрече разработчиков приложений для iOS и OS X CocoaHeads Moscow, я рассказывал про новую концепцию Size Classes, представленную Эплом на WWDC-2014. Это совершенно новый способ построения адаптивных интерфейсов для айос-дивайсов. Немного коснулся интересных тонкостей о том, как их использовать в приложениях на айос-8, и как их бекпортить на айос-6.

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

Очень интересно, какие вопросы появятся у читателей моего блога. Буду рад ответить :)

На этой встрече также докладывал Михаил Байнов про массивы и структуры ANSI C/C99, и Саша Зимин рассказывал материальный дизайн кнопок из нового Андроида-Л и показывал как это сделать на Свифте; с его презентации также доступны слайды.

Upd. Видеозапись доклада: http://blog.m4rr.ru/all/size-classes-addition/

2014   CocoaHeads   iOS   Objective-C   Swift   Xcode

Как не показывать эмоджи в UILabel

Мы с другом сейчас работаем над одним очень интересным проектом, который выйдет осенью, вместе с Айос-8. И в этом проекте появилась задача: показать некоторые стандартные юникодные значки. Но, оказывается, если эти символы добавить в UILabel, то айось заменит их на картинки-эмоджи. Это, конечно, круто, но не то, что нам нужно.

Emoji UILabel

Я ничего не знал о том, как работают эмоджи, поэтому пришлось провести небольшой рисерч. Оказывается, в юникоде есть такая штука как variation selector. Он документирован в стандарте с 3.2.0, а сейчас уже — 6.0.

variation sequence, which always consists of a base character followed by the variation selector, may be specified as part of the Unicode Standard. That sequence is referred to as a variant of the base character. The variation selector affects only the appearance of the base character,* and only in the variation sequences defined in this Standard. The variation selector is not used as a general code extension mechanism.
Источники: раз, два.

Итак, variation sequence — последовательность, которая состоит из базисного символа и следующего за ним модификатора (variation selector). Такая последовательность ссылается на вариацию базисного символа. Модификатор влияет только на внешний вид символа.

Таким образом, юникодный символ, для которого существует эмоджи-картинка, мапится в эмоджи. Но существует такой модификатор U+fe0e, который, будучи добавленным к юникодному символу форсит выбор не-эмоджи варианта символа.

Короче, можем написать любой символ (U+2709 — для конверта), и к нему U+fe0e:

// Swift:
label.text = "Привет, посылаю тебе ✉︎\u{fe0e} не из этой страны"
// Objective-C:
label.text = @"Привет, посылаю тебе \U00002709\U0000FE0E не из этой страны";

И получить то, что нужно:

Non-emoji UILabel

(Кстати, есть еще кодировка эмотиконов Softbank, которая используется в смс. В опенсорсе на сайте Эпла есть таблица их мапинга в эмоджи и обратно: Any_SoftbankSMS.txt)

2014   Objective-C   Swift   Unicode   Xcode

Как поставить кнопки друг к другу

Иногда в интерфейсе айос-приложений нужно расставить кнопки друг к другу, чтобы ширина у всех автоматически стала одинаковой, как, например, в старом добром Тотал-командере:

Кнопки Тотал-коммандера

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

С появлением Size Classes в iOS 8, становится понятно, что любой другой способ получается слишком громоздким. Поэтому, задача расставления кнопок (UIButton или вообще любой UIView) сводится к правильной расстановке констрейнтов автолейаута.

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

Damn auto layout!

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

Good auto layout.

Ура!

2014   Objective-C   Swift   Xcode

Как удалить все сабвьюхи

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

Например:

[self.view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

Метод `removeFromSuperview` — это обычный метод вьюхи, чтобы самовыпилиться. Метод `makeObjectsPerformSelector` — это метод NSArray, чтобы выполнить селектор всем его элементам.

А на Свифте, например, так:

for subview in view.subviews as [UIView]   {
  subview.removeFromSuperview()
}

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

view.subviews.map { $0.removeFromSuperview() }

Вот так можно удалить все сабвьюхи.

2014   code   Objective-C   Swift

Свифт-хакатон от CocoaHeads Moscow

На прошлых выходных ребята из CocoaHeads Moscow устраивали первый (в мире?) Свифт-хакатон. (Свифт — это новый язык Эпла для программирования под Айось и Макось.) Хакатон проходил в Москве, в офисе Мейл.ру два дня подряд.

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

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

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

Стоит отметить, что, конечно же, есть гемы и другие серверные решения для этой задачи. А в нашем случае парсинг происходит непосредственно на айос-устройстве. Потому что это Свифт-хакатон!

Мы стали экспериментировать с подходами к разработке. Создали два таргета в Икскод-проекте, две ветки в Гите (и потом задолбались их мерджить, но зато комильфо!) А также проектирование, прототипирование, какао-поды и т. д.

Столкнулись с кучей проблем и интересных решений. Расскажу подробнее. Есть несколько основных способов узнать что является основным текстом среди всего контента веб-страницы:

  • вытащить текстовые хтмл-теги (article, h1...6, p и т. д.), но это не везде хорошо работает
  • поискать самый длинный контент в тегах, но это не гарантирует основной текст
  • посчитать количество точек в каждом теге и, где больше, — там основной текст, но это жесть
  • предложить юзеру указать на основной текст, лол

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

За рамками отведенного на хакатон времени еще осталась куча придуманных фич. Но в результате получилось 139 коммитов, и отличная база для дальнейшей работы.

Все проекты лежат на гитхабе CocoaHeads Moscow:

Спасибо CocoaHeads Moscow и огромное спасибо компании Мейл-ру. Было здорово!

Здание Мейл-ру и вид из офиса во время рассвета:

Value overflow

“[In Swift] Arithmetic operators (+, -, *, /, % and so forth) detect and disallow value overflow, ...”

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l

2014   in English   Swift

Swift

В этом году даб-дабе (WWDC 14), как все уже знают, Эпл представила новый язык разработки — Свифт.

Свифт — современный и клевый язык для работы с Какао и Какао-тач (Cocoa, Cocoa Touch). И, так как этот блог был про всякие классные штуки в ОбджСи, то теперь это одновременно и блог про всякие классные штуки в Свифте! :)

Кстати, в одной из сессий на даб-дабе рассказали, что ОбджСи все равно останется важным:

И обратите внимание на колонку «Хорошие блоги» слева. Там сейчас про ОбджСи. Но скоро все поменяется :)

2014   Objective-C   Swift   Xcode