Дневник разработки · День 9

Пятнадцать лет опыта, лучшие модели — и это всё ещё не магия

🔌 Engineer honesty moment

Сегодня для разнообразия начну не с того, что сделал, а с вопроса к вам — тем, кто на той стороне.

Это девятый день. Если вы прочитали всё, что было до него, скажите честно: ведь не мне одному кажется, что эта на первый взгляд тривиальнейшая история оказалась совсем не такой простой?

Сейчас на презентациях то и дело кто-нибудь выходит на сцену и показывает, как в три счёта собрать агрегатор авиабилетов. Или переводчик. Или что-нибудь ещё. В теории звучит прикольно, и продукт это продаёт.

На практике, когда тебе нужна вполне конкретная вещь, такие быстрые результаты не подходят.

Быстрый результат у меня был. На четвёртый день. И в нём не было поля ввода.

Можно сказать: ну, ты просто не умеешь, забиваешь гвозди микроскопом.

Нет. Я не ноль в разработке. У меня за спиной пятнадцать лет программирования и самые сильные модели, какие сейчас вообще есть. И всё равно задачка, которая звучит тривиально, растянулась на совсем не слабый кусок времени.

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

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

Разработка — это жёстко. Если, конечно, ты хочешь сделать что-то, что имеет ценность.

А делать ерунду — попробуйте. Только хватит ли у вас мотивации продолжать и тратить на неё своё время?

Вопрос не риторический.

⏳ Четверг

А теперь — что было сегодня.

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

У ИИ, с которым я работаю, недельный лимит. Моя неделя кончается в четверг.

Однажды я спалил весь недельный лимит за три дня. Остаток недели был тоскливым: всё, что хотелось сделать, упиралось в «потом».

С тех пор у меня перекос на четверг. Я знаю, что запас ещё есть и что скоро он всё равно обнулится, — и трачу его интенсивнее, чем в любой другой день.

А аудит — самое дорогое, о чём можно попросить. Поэтому он и случился вчера вечером.

Я попросил ИИ пройтись по всему коду так, будто он ревьюер App Store, которому платят за то, чтобы найти причину отказать.

Сегодня опять поезд. Четыре часа дороги туда и обратно — достаточно, чтобы прочитать результат не наискосок, а обстоятельно.

🗺 Карта

На выходе — не список замечаний, а карта.

Четыре прохода параллельно: качество кода, безопасность, готовность к магазину, тесты. Самые тяжёлые находки перепроверены отдельно, по исходникам, а не по памяти.

Четыре пункта — «загрузку отклонят сразу».
Пять — «критично».
Пятнадцать — «важно».
Двадцать — «по мелочи».

И отдельный раздел, который мне понравился больше всех остальных: «проверено, не чинить».

Шифрование. Замки. Поиск. Буфер обмена. Аудит прямо пишет: вот это устроено правильно, не трогайте.

Мне кажется, это самая недооценённая часть любого ревью. Сказать, где всё хорошо, — это не вежливость. Это защита от следующего, кто придёт «улучшать».

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

📦 Что ехало внутри

Первый из четырёх пунктов «отклонят сразу» — у приложения нет песочницы. Mac App Store такое не принимает в принципе. Это скучно, это чинится за десять минут, и это ровно то, чего я про платформу Apple не знал.

А вот второй.

Помните день, когда открылся Xcode? Я тогда скопировал документы проекта внутрь папки приложения. Стратегию, требования, план, все файлы задач. И написал, что копий теперь три, байт в байт, и одна из них — внутри самого приложения.

Оказалось, «внутри самого приложения» — это не фигура речи.

Мы ещё на четвёртый день выяснили, что в Xcode всё решает папка. Всё, что лежит в этой, он упаковывает в приложение. Так что каждый, кто купил бы jpaste, получил бы вместе с ним мою стратегию. Позиционирование. Цену и почему именно она. Список того, что я планирую сделать, и в каком порядке.

Двенадцать файлов. Шесть с лишним тысяч строк. Там даже есть раздел «Почему $9.99, а не $4.99».

Стыдно мне не было. Всё это ещё в разработке, в магазин ничего не ушло. Цена в документе — та, что стоит сейчас. Может, я её ещё переделаю. Посмотрим.

Но раз уж вчера я спросил о цене вас, честно будет ответить самому. Не как автор jpaste, а как покупатель.

По подписке мой лимит — ноль. Ещё одна ежемесячная строчка в выписке мне неинтересна.

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

Сегодня этих файлов внутри приложения нет.

Сегодняшний коммит удалил почти девять тысяч строк и добавил четыре с половиной. Вдвое больше удалено, чем добавлено.

Только кодом из удалённого были триста строк. Ещё две тысячи — переписанные переводы. А остальное — мои собственные документы, которые возвращались туда, где им место.

Двенадцать файлов, шесть тысяч триста шестьдесят одна строка — внутри приложения. Кода среди них нет.
Двенадцать файлов, шесть тысяч триста шестьдесят одна строка — внутри приложения. Кода среди них нет.

🔐 Сейф, до которого я наконец дошёл

Два дня подряд я писал про сейф одно и то же: всерьёз ещё не тестировал, блок большой, тестировать и тестировать.

Сегодня до него дошло.

И главная находка была ровно того сорта, которого я боялся.

Если настройку сейфа прервать посередине — закрыть окно, отменить, уронить приложение, — доска оставалась помеченной как сейф, а содержимое лежало открытым текстом. Замок висит, двери нет.

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

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

  • скрытый сниппет, скопированный в буфер, теперь исчезает оттуда через минуту
  • пока открыта защищённая доска, окно не попадает в запись экрана
  • горячие клавиши больше не могут отправить пароль не той доске

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

Тестов утром было семьдесят два. Вечером — сто три.

🗳 Решения, которые за меня никто не примет

Часть пунктов аудит пометил: «решение владельца, без него не трогать». Их было шесть.

Про чит-код — в первую очередь.

Аудит сформулировал его вежливо, но прямо: скрытая функция, которая меняет то, за что берут деньги. Ревьюер такое, скорее всего, не найдёт. Но если найдёт — это ровно то, за что правила магазина наказывают.

Вариантов было два. Оставить только молнии и убрать бонус. Или оставить всё и честно написать об этом в заметках для ревьюера.

Я оставил всё.

Я уверен, что описание приложения в магазине почти никто не читает внимательно. Значит, в нём можно спокойно и прямо написать про чит-коды — и проблемы не будет.

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

А те, кто читает этот дневник, о нём и так уже знают.

Второе решение мне нравится больше всех.

Аудит показал: защищённую доску можно было удалить, ничего не подтверждая. Злоумышленник, добравшийся до открытого приложения, просто стёр бы её. Это небезопасно, и это настоящая дыра.

Очевидная заплатка — спрашивать пароль сейфа. Но я подумал вот о чём.

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

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

Поэтому удаление теперь спрашивает Touch ID. Не пароль сейфа — отпечаток владельца Mac.

Раньше защиты не было вовсе, теперь она есть. И забытый пароль больше не оставляет тебе мёртвую доску, которую не открыть и не убрать. Приложил палец, удалил, живёшь дальше.

💬 Вопрос

Аудит удалил вдвое больше, чем добавил, и самым ценным в нём оказалось то, что велели не трогать. Но вопрос у меня сегодня один — тот, с которого я начал.

Быстрый результат позади, до настоящего ещё далеко. Что держит вас в проекте, когда он перестаёт быть быстрым? И бросали ли вы, когда понимали, что это надолго?

Расскажите, как у вас 👇

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

И у меня нехорошее подозрение, что столько изменений сразу не проходят бесследно. Ночью хочу, чтобы эту правку прочитал кто-то, кто её не писал 😉