Блог о страсти к программи­рованию, дизайну и путешествиям

m4rr.ru  •  резюме  •  medium in english

Позднее Ctrl + ↑

Авторизация в Московском метро

cover black

Обновлено—2. Приложение для авторизации в метро для iOS появилось Апсторе!

Обновлено. Бета-тестирование завершилось. Спасибо всем за участие! «Москва. Метро. Авторизация вайфай» отправилось в Апстор на проверку. Нет рекламе прокладок в Московском метро! Подписывайтесь на меня в твитере @m4rr — следите за новостями. А пока зацените мой стартап — Paste.

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

Новый логотип вайфая

За две недели в бета-тестирование было выпущено 10 билдов. Спасибо дорогим бета-тестерам за фидбек! Отдельное спасибо @iShift за помощь в построении гипотез, и @r3s3t за прекрасную иконку!

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

Это приложение пока не в Апсторе Если вы хотите его попробовать — напишите мне письмо и я отправлю вам приглашение.

***

Проблема разработки такого приложения в том, что тестировать его очень сложно. За время поездки на метро, нужно придумать гипотезу, почему очередной способ не сработал. Вечером дома обновить алгоритм, и только на следующий день проверить работу нового алгоритма. Дальше процесс повторяется. Такой замедленный хакатон.

За время работы над приложением я подробнее узнал про сетевой сервис Captive portal, который для этого и был создан. Как это работает?

Айось, после подключения к вайфаю, делает первый запрос на какой-нибудь captive-check.apple.com, и если получает ожидаемый ответ, то считает, что интернет доступен. Если ответ неожиданный — показывает специальное окно, в котором загружается страница логина. В Старбаксе, например, именно так.

Но разработчики авторизации в метро специально [1, 2, 3] пропускают запрос на каптив-портал, и айось получает ожидаемый успешный ответ. Но если после этого, вы пытаетесь открыть любой сайт, то вместо него вы все равно получаете страницу авторизации! И новости про Coбянинa, конечно.

Короче, я считаю, что это неправильно, и приложение отлично с этим справляется!

Open Source! [BY NC SA]

0.1 + 0.2

Присылают мне сегодня комикс про Джаваскрипт. Разберем его.

Комикс про Джаваскрипт

Я, было, подумал, что шутка в том, что сложить в Джаваскрипте можно что угодно с чем угодно. Но, оказывается, шутка в том, что сумма будет равна 0.30000000000000004, и это, типа, жесть :-)

Я проверил в Руби и Питоне, результат такой же:

irb(main):001:0> 0.1 + 0.2
=> 0.30000000000000004

>>> 0.1 + 0.2
0.30000000000000004

Так вот, это не шутка. Но почему не 0.3?

Потому что 0.3 в принципе не представими в виде плавающей точки, возможно*.

Плавающая точка — это, фактически, представление числа на неравномерной сетке, с нелинейным шагом, который зависит от числа. Около 1 шаг будет, грубо говоря, 1/10⁹, а около 10⁹ это уже будет 1.

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

То есть, в памяти — не то, что ты думаешь и печатается не то, что ты думаешь :)

Сноска *: В данном случае, погрешность, может, и правда, из-за перевода в основание 2:

0.3₁₀ = 0.01001100110011(0011)₂

Короче, можно просто считать, что никогда не стоит доверять плавающей точке и всегда использовать fuzzy compare.

Тема очень интересная. Discuss!

И, конечно, огромное спасибо Саше за консультацию!

2015   code   edu   math

Фото-блогерский тур в Узбекистан

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

Заглавная картинка из жж puerrtto

Если вы или ваши друзья хотят присоединиться к такой поездке — мы только за!

cover! black

В программе:

  • Ташкент и окрестности;
  • Самарканд и область;
  • Ферганская долина;
  • Бухара и остатки каганата;
  • крейзи: пустыня Кызылкум на междуречье Амударьи и Сырдарьи;
  • совсем крейзи: Каракалпакстан и Аральское море;
  • крейзи-мазафака: Туркменистан и газовый кратер Дарваза.

Это путешествие имеет две особенности:

  • •  красиво, интересно и познавательно;
  • •  полный бардак в экономике страны.

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

Так или иначе, до начала путешествия рекомендую поскролить лонгриды Темы, 2002 и Puerrtto, 2015 про Узбекистан.

Задавайте вопросы в комментариях, если хотите присоединиться.

2015   edu   in English

Сплав по Имандре и поход по Хибинам

В России невероятно красивая природа. Чтобы на нее посмотреть, разумеется, надо уехать за 1700 км от Москвы. Я никогда раньше не был нигде севернее Санкт-Петербурга. Этим летом мы с друзьями пошли в поход — в Мурманскую область. Неделю мы сплавлялись на байдарках по озеру Большая Имандра, и три дня были в горах — Хибинах.

Имандра — самое большое озеро Кольского полуострова. Прекрасный вид:

Первым открытием для меня стало то, что за Полярным кругом, конечно же, не вечная мерзлота, и в июле воздух прогревается аж до +15 °C. Там живут люди, животные, а также 100500 миллионов комаров и мошек. Там, вроде, немного туристов, поэтому везде почти чисто.

cover! transparent

Вторым открытием был полярный день. Я никогда не попадал в Петербург на белые ночи, поэтому не видел ничего подобного. Я знал, что (в теории) Солнце не заходит за горизонт. Но когда видишь, что Солнце не заходит за горизонт никогда — это здорово удивляет! 2 часа ночи:

Два часа ночи: «рассвет» на о. Высокий в Мурманской области

Мы прошли 100 км на байдарках по озеру, и 25 км пешком по горам. Примерно по такому маршруту:

По нашему маршруту мы шли к Хибинам вдоль Медвежьего ручья — притока Имандры — от его устья до истока. Перед выходом мы зарегистрировали нашу туристическую группу в местном МЧС. Там же нам сообщили, что медведи в этих краях, да, встречаются. Чем вовсе не успокоили.

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

За три дня горного похода мы дважды ночевали в долине ручья — в лесу. Как мне известно, все, что могут сделать обычные туристы перед ночевкой для предостварещения встречи с дикими животными — это: развести костер, шуметь, раскидать вещи в 20 метрах вокруг лагеря. При ходьбе держаться кучнее. При встрече с медведем — главное — не убегать, и нет смысла лезть на дерево; нужно медленно отходить. Если встретить медвежонка, то всё.

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

Особенно сложной частью похода был перевал через невероятно красивый горный разлом в Хибинах: перевал Почтальон / третья щель. Мы прошли 6 или 7 таких высоких 10-метровых спусков и подъемов.

Выходишь из ущелья разлома, а дальше снова красота:

Нетипичная фотка из отпуска:

Интересные ссылки:

Обновлено. Художественный рассказ про наш поход от другого участника: «Как я выживал в походе. Исповедь городского растения».

Про США: часть первая

В апреле этого года я в первый раз полетел в США. На три недели. В Калифорнию!

cover! transparent

Перед поездкой я прочитал, что когда-то существовал прямой рейс SVO—SFO, но лет 5 назад его отменили. Теперь в Сан-Франциско из Москвы можно долететь только с пересадкой. Мы летели с пересадкой в Нью-Йорке, и это категорически неудобно.

SVO ✈︎ JFK (9 часов) + стыковка (2...4 часа) + JFK ✈︎ SFO (6 часов)

Как нам позже рассказал Саша Киров из Пеббла, намного удобнее лететь через Лос-Анджелес. (В следующий раз так и сделаю! И вам советую :)

О трех неделях в штатах можно рассказать много всего. Я решил разделить рассказ на три части: про США в целом, про Долину и стартапы, и про СФ в частности.

Кстати, Сан-Франциско не является частью Кремниевой долины. Долиной считается нижняя часть полуострова примерно от Пало-Альто до Сан-Хосе:

Начнем.

Культурный шок

В США, начиная с аэропорта, встречаешь вокруг людей у которых немного иной культурный слой и немного иное воспитание, чем у нас в суверенной духовно-скрепной Россиюшке. Да что там с аэропорта? Прямо в самолете перед нами сидела женщина, которая полностью была укрыта паранджой. Но она ведь прошла все службы безопасности и досмотр, правда же? В России редко такое можно увидеть, а тем более — столкнуться.

Так вот, так вот. Китайцы ведут себя в соответствии со своим культурным кодом, индусы и египтяне — со своим, и все это в одной стране, в одном городе, на одной с тобой улице. Это немного странно, и я к этому так и не привык. Но толерантность говорит, что это не твое дело, как другие люди ведут себя в свободной стране.

Культурное удивление

Большим удивлением в штатах стало то, что никто не знает про группу Раммштайн, из тех, с кем я общался. Это вообще как? Я был уверен, что это всемирно известная группа, и нет никого на Земле, кто не знал бы о ней. Но не знают о Раммштайне ни живущие в Калифорнии с рождения американцы, ни египтяне-стартаперы. Но всем нравится, если включить Ду-хаст. Или это просто вежливо так говорить?

Культурное ок

Но многообразие культур дает возможность поговорить с интересным водителем Убера, например. Однажды меня подвозила прекрасная женщина из Канады, которая уже 30 лет живет в Маунтин-Вью. Мы с ней здорово пообщались по-английски, и по-французски, раз она из Монреаля. Еще можно поставить белый рэп черному водителю Убера через Спотифай.

Да, в Долине очень популярен Убер. Приезжает за пару минут.

P.S.

Ден проспорил, что к поездке он успеет опубликовать свой новый сайт. Теперь, по условиям спора, его сайт должен быть сверстан Комик-сансом. Ждем анонса :)

Пара скриншотов к 1 апреля

cover black

В рамках 1 апреля выложу пару старых скриншотов:

Изменение дизайна кнопок в Винде 7—8:

Хром потерял соединение:

Фотографии одной из книг, уцелевших в библиотеке ИНИОН. Вот, например, изданная в 1687:

Магия после установки программ iWork:

Список желаний

Записал для друзей (что тебе подарить?) и для себя (куда бы потратить деньги?) список желаний:

wantr.ru/m4rr

2015   lytdybr

Что такое автолэйаут

Некоторые знакомые менеджеры и другие ребята спрашивают меня: что такое автолэйауты в Икскоде? Задают вопросы, типа: «можно сказать что много аутолэйаутов?», «сложный аутолэйайт?», «бывает сложная работа по ним или легкая, например?»

Я пытался уклончиво сказать, что это «распорки», и отправить в документацию Эпла с картинками. Но этого не хватило. Попробую описать тут.

Короче, автолэйаут — это одна из концепций построения интерфейса Айос-приложений.

TL;DR

Автолэйаут появился в Икскоде с версии 4.5 и в Айос-6. Автолэйаут можно выключить, и пытаться строить интерфейс без него. В простых интерфейсах это прокатывает, но в сложных — нет. (Хотя, некоторые выключают и в сложных.)

(См. также мой доклад про Size Classes.)

Так вот, когда автолэйаут включен, то интерфейс строится с помощью «распорок» (constraints), которые контролируют поведение при растягивании и сжимании.

Справа написано, какие 7 распорок установлены на простую надпись (это много), а слева почти все показаны:

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

2015   Xcode   дизайн

Как я получил визу США

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

cover! black

Консульский отдел посольства США мне понравился больше, чем консульства всех европейских стран, в которых я был. Тут никто не запрещает ходить и перемещаться по зданию. Есть даже автоматы с едой и напитками, и туалет.

На весь процесс ушло 3 часа — с 9 утра до 12. Людей было много, поэтому везде очереди: на вход, на талон электронной очереди, на регистрацию, на дактилоскопию, на собеседование с консульским офицером.

Консул спросил цель визита, спросил куда я еду, спросил говорю ли я по-английски. Потом по-английски спросил чем я занимаюсь. Я все рассказал, и он ответил, что виза одобрена и привезут через неделю. (А привезли через два дня.)

Интересно, что консульский сбор за визу стоит минимум 11 200 ₽. Самый большой номер в электронной очереди на этот день был 300. 300 человек в день × 11 200 ₽, ого!

Шенген, например, ≈ 2500 ₽.

Апдейт. Странная штука — блоги, вместо того, чтобы задать вопросы в комментариях, мне их задают лично :) Отвечаю:

То есть ты получил визу за 2 дня!? Или как это вообще происходит?
Мне прямо там консульский офицер сообщил, что виза одобрена. А привезли на пони-экспрессе через два дня, да.

То есть ты просто пришел в посольство с документами и все? Я думала, там записываться надо на собеседование... А билеты не обязательно иметь на руках, насколько я помню, да?
Ну, сначала я заполнил 20-страничную анкету, потом заплатил пошлину, записался, и потом пришел с документами, да. Больше ничего не нужно. Я даже выписку из банка не показывал.

А за сколько ты записывался?
В пятницу — на среду. (ПН был выходной — 23 февр.)

Задавайте ваши :)

Новый год

Весь прошлый год я ответственно вел календарь и записывал в него все самое интересное и важное. Получилось здорово и насыщено:

За это время поменялся дизайн ОС Х, ср. с прошлым годом.

Как и обещал в прошлом январе, я завел много новых знакомств и много путешествовал: дважды был в Германии и Нидерландах, и по одному разу в Италии, Турции и Сан-Марино. Проехался на механике от одного берега Италии — адриатического — до другого — тирренского, и обратно.

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

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

Збс!

Сноуборд

Ура, с начала этого года я катаюсь на сноуборде! Точнее — с конца прошлого.

В 60 км на север от Москвы — в районе Яхромы — находятся холмы, и на них расположились несколько горных спортивных комплексов: Волен, Степаново, Сорочаны и т. д. Там небольшие склоны, небыстрые подъемники, но это лучшее, что есть вокруг Москвы, как я понял.

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

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

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

Ко второму разу я уже купил офигенные сноубордические штаны, защитные шорты, которые защищают копчик (что очень важно!) и маску от ветра. Так намного удобнее.

На пятую поездку в горы, у меня получилось разогнаться до 33 км/ч, и делать красивые дуги на поворотах. И особенно клево, что трекеры для айфона записывают и показывают траекторию движения и другие параметры моего спуска и характеристики склона:

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

@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

Новый свежий сайт

cover black

Примерно пять лет назад я придумал дизайн сайта с картой своих путешествий; тогда я посетил всего около 40 городов.

За это время на сайте менялись карты Гугла и Яндекса, рандомно включались режимы «схема», «спутник» и т. д. Маркерами на карте когда-то были флажки, потом стали пины с названиями городов. На нем всегда была актуальная информация о путешествиях, но со временем он перестал быть симпатичным.

Для сайта появились новые задачи: рассказать обо мне, показать резюме, дать ссылки на мои профили на Гитхабе и Стековерфлоу. К этому времени я побывал в 69 городах, и вот, наконец, обновил свой сайт! m4rr.ru 4.0:

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

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

Версия 4.1 будет показывать, где я нахожусь прямо сейчас (из Форсквера :)

Скриншоты

Вот какие клевые выпадающие меню теперь — в айос-8 — получаются на айфоне в горизонтальном сайз-классе:

Дополнение про Size Classes

Сегодня появилась видеозапись моего доклада на августовской встрече разработчиков CocoaHeads Moscow. Ура!

Хочу еще немного добавить про особенности сайз-классов. В докладе я немного упомянул про специальные отступы от границ экрана. Это Leading Margin и Trailing Margin по бокам, и Top и Bottom Layout Guides сверху и снизу.

Leading Margin и Trailing Margin по бокам, и Top и Bottom Layout Guides сверху и снизу.

Например, вы проектируете единый интерфейс для айфона и айпада. И нужно сделать так, чтобы на разных дивайсах у кнопок, расставленных по бокам, были ожидаемые пользователем отступы. Для этого можно расставить кнопки именно относительно ведущего — слева — и замыкающего — справа — отступа. То есть, если нативный отступ слева на айфоне — это 8 пк, а на айпаде — 20 пк, то кнопки автоматически встанут как надо.

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

Кроме того, интересно, что Leading и Trailing Margin меняются местами, если на устройстве установлен какой-нибудь язык, который пишется справа налево (RTL). Для обычных LTR-языков они находятся слева и справа, соответственно.

2014   CocoaHeads   iOS   Xcode

Скриншоты

Не очень люблю постить скриншоты куда-либо, но иногда попадается что-нибудь жутко интересное. Например, Эпл в своих приложениях стала использовать индикаторы загрузки (или даже HUD):

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

Или вот, например, официальное приложение Билайна заставляет клиентов вводить номер телефона, который и так известен этому приложению. И капчу:

Мир несовершенен, но мы знаем, как его улучшить, чо :)

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

Что я узнал про Амстердам

Никогда раньше не был в Западной Европе на католическое рождество. Я подумал, что это должно быть интересно, и поехал на рождество в Нидерланды. Оказалось, что это самая атеистическая страна Европы.

В этой поездке была куча экспериментов:

  • Я впервые не бронировал гостиницу заранее, потому что интересно, как это.
  • Впервые не брал с собой наличные деньги.
  • Впервые отменил обратный билет и путешествовал по Европе не думая, когда полечу обратно.
  • Впервые решил пользоваться в поездке искючительно пластиковой картой, чтобы накопить миль в Рокетбанке :)

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

В Амстердаме клево. Три дня из пяти погода была отличная. Остальные два дня шел дождь, но как-то он не мешал. Была отличная компания и хорошая одежда. (Нет плохой погоды — есть плохая одежда же.) В это время к нам в гости приехали ребята из Франции, привезли самогон из подвала дедушки одного из ребят, сидр и яблочный сок (тоже из подвала дедушки).

Обратите внимание на балаклаву!

Оказалось, что рождество в Голландии отмечается в узком семейном кругу, и на улицах ничего особенного не происходит. В Нидерландах два рождественских выходных: первые (eerste) и вторые (tweede) kerstdag. Девушки на Красных фонарях тоже, видимо, в семейном кругу: они не работают в эти дни.

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

Я был в Амстердаме 6 дней, и в конце декабря поехал в Берлин к ребятам в aic labs. Позже я снова вернулся в Амстердам на выходные в феврале. Скоро напишу.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 Яндекс.Карты

Яндекс теперь показывает подписи к объектам на своих картах. Очень интересно и клево. Сейчас бывают ошибки в подписях, например, Академию ФСБ на Юго-западе подписали как какую-то церковь. Но для таких случаев, прямо на карте можно сообщить об ошибке (что я и сделал :-)

Но еще очень интересен формат подписей. Или даже дизайн:

Яндекс-карты

Если присмотреться, то можно заметить, что эти подписи совсем не похожи на гугловские. У Гугла там вообще мрак:

Гуглокарты

А если присмотреться еще внимательнее, то можно подумать, что Яндекс выбрал Apple way:

Эпл-карты

Круглая иконочка, цветовое кодирование, короткий текст, подпись снизу.

Выглядит, как-будто Яндекс подготавливает выдачу в стиле Эпла (хотя, на самом деле — близкую к здравому смыслу). Если Эплу вдруг понадобятся более правдоподобные данные для России, то у Яндекса, например, все уже будет готово.

Яндекс и сейчас предоставляет Эплу метаданные, например, о времени работы организаций. Может, Яндекс хочет стать не просто провайдером метаданных, но и провайдером вообще всех данных на картах Эпла? Круто, если так!

2014   Яндекс

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

Пятая колонка

Редко вижу верстку титров в 5 колонок. Слава 16×9!

Титры к фильму в формате 16×9
2014   кино

UIViewContentModeScale

typedef NS_ENUM(NSInteger, UIViewContentMode) {
    UIViewContentModeScaleToFill,
    UIViewContentModeScaleAspectFit,
    UIViewContentModeScaleAspectFill,
    ...
}
UIViewContentMode

UITableViewCellStyle

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
    UITableViewCellStyleDefault,
    UITableViewCellStyleValue1,
    UITableViewCellStyleValue2,
    UITableViewCellStyleSubtitle
};
UITableViewCellStyle
Ранее Ctrl + ↓