<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>@easy_dev991</title><subtitle>Делюсь интересными находками/лайфхаками в процессе разработки под iOS, и возможно ты найдешь что-то полезное для себя!</subtitle><author><name>@easy_dev991</name></author><id>https://teletype.in/atom/easy_dev991</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/easy_dev991?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@easy_dev991?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=easy_dev991"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/easy_dev991?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-08-13T15:12:48.546Z</updated><entry><id>easy_dev991:ViI6fuwfx8C</id><link rel="alternate" type="text/html" href="https://teletype.in/@easy_dev991/ViI6fuwfx8C?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=easy_dev991"></link><title>Баги в проде неизбежны, и при чем тут тесты</title><published>2026-08-08T12:47:25.705Z</published><updated>2026-08-08T12:47:50.771Z</updated><category term="test" label="Test"></category><summary type="html">6 лет назад, когда я ходил по собесам на джуна/миддла, почти все команды говорили мне, что не пишут тесты, но при этом у них в проде &quot;все ок&quot;. Конечно, они просто нагло врали, да и какое дело? Зарплату платят и норм, так ведь? При этом мне хочется видеть в проде меньше багов. Как бы мы ни старались, баги будут в любом случае, разберемся в этом.</summary><content type="html">
  &lt;p id=&quot;7wfP&quot;&gt;6 лет назад, когда я ходил по собесам на джуна/миддла, почти все команды говорили мне, что не пишут тесты, но при этом у них в проде &amp;quot;все ок&amp;quot;. Конечно, они просто нагло врали, да и какое дело? Зарплату платят и норм, так ведь? При этом мне хочется видеть в проде меньше багов. Как бы мы ни старались, баги будут в любом случае, разберемся в этом.&lt;/p&gt;
  &lt;p id=&quot;utpp&quot;&gt;И речь в основном будет про автотесты, а не ручное тестирование.&lt;/p&gt;
  &lt;h2 id=&quot;maQd&quot;&gt;Что я понимаю под багом&lt;/h2&gt;
  &lt;p id=&quot;GiPX&quot;&gt;Как мобильный разработчик, я называю багом то, что работает неправильно, не работает, или приводит к полной невозможности пользоваться приложением, например:&lt;/p&gt;
  &lt;ol id=&quot;3pjh&quot;&gt;
    &lt;li id=&quot;FLET&quot;&gt;кнопка не нажимается, хотя она подсвечена как активная, и по логике в коде она точно должна нажиматься, т.е. нет никаких объективных причин для ее блокировки&lt;/li&gt;
    &lt;li id=&quot;ddSn&quot;&gt;элемент на экране нажимается, но в редких ситуациях, т.е. проблема с зоной нажатия&lt;/li&gt;
    &lt;li id=&quot;uX5r&quot;&gt;что-то на экране не отображается, или уехало куда-то в сторону, сжалось или растянулось, т.е. выглядит плохо, не как задумано&lt;/li&gt;
    &lt;li id=&quot;UYLG&quot;&gt;приложение само закрывается при выполнении какого-то действия (крашится)&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;k5Ui&quot;&gt;Первые 3 примера часто не считаются критичными, потому что приложение же работает, так?&lt;/p&gt;
  &lt;p id=&quot;yxDU&quot;&gt;Четвертый уже не так просто игнорировать - статистика по крашам приложения видна во всех популярных инструментах типа firebase, и тут уже не отвертишься - там это включено по умолчанию, если конечно в проекте подключен firebase.&lt;/p&gt;
  &lt;h2 id=&quot;HRf8&quot;&gt;Что я не считаю багом&lt;/h2&gt;
  &lt;p id=&quot;jXYf&quot;&gt;То, что было сделано по задумке команды (дизайнеры/аналитики/продакты и т.д.). Если чтобы добраться до какого-то меню, нужно пройти 7 кругов ада из бесполезных переходов по нескольким экранам, то это не баг, а &amp;quot;фича&amp;quot;. Так кто-то задумал, и разработчик сделал по требованию в задаче.&lt;/p&gt;
  &lt;p id=&quot;BcWi&quot;&gt;Или если в приложении используются вырвиглазные цвета, некрасивые иконки/картинки - ситуация та же.&lt;/p&gt;
  &lt;p id=&quot;1A1N&quot;&gt;При этом разработчику могло не нравится это решение, он мог даже высказать свое мнение команде или конкретному лицу, принимающему решение по этому функционалу, но его мнение могло быть легко послано на все 4 стороны, потому что не все и не везде хотят/готовы слушать мнение разработчика, когда есть заказчик с его хотелками и &amp;quot;видением&amp;quot;.&lt;/p&gt;
  &lt;p id=&quot;mrDL&quot;&gt;Заказчиком, кстати, может быть кто-угодно - это необязательно какой-нибудь акционер или директор, или клиент. Кто-угодно может быть заказчиком в зависимости от ситуации.&lt;/p&gt;
  &lt;h2 id=&quot;aFp5&quot;&gt;Тесты&lt;/h2&gt;
  &lt;p id=&quot;wHud&quot;&gt;Опустим страшные истории про бородатые времена, когда тесты нужно было учиться писать, писать их вручную и страдать, страдать как никто другой никогда не страдал, ведь это не просто нужно сделать самостоятельно, а еще и в очень короткие сроки, потому что бизнесу тесты не нужны, и вообще никому не нужны тесты, а нужны фичи... да?&lt;/p&gt;
  &lt;p id=&quot;o5Yl&quot;&gt;Хотел повеселиться немного, ведь мне такую дичь часто говорили в прошлом)&lt;/p&gt;
  &lt;h3 id=&quot;sQUC&quot;&gt;Unit-тесты&lt;/h3&gt;
  &lt;p id=&quot;b64t&quot;&gt;Итак, у нас есть тесты. Пусть это unit-тесты, и вообще не на все приложение, но в целом тесты есть и они даже выполняются на каждый мерж-реквест - вероятность что-то сломать, задев уже протестированную логику снижается.&lt;/p&gt;
  &lt;p id=&quot;Hq3a&quot;&gt;И все же баги попадают в прод, потому что ... тесты не покрыли все места приложения.&lt;/p&gt;
  &lt;p id=&quot;j0SG&quot;&gt;Команда напрягается и повышает процент покрытия тестами.&lt;/p&gt;
  &lt;p id=&quot;qZlS&quot;&gt;И баги снова возникают. Что дальше?&lt;/p&gt;
  &lt;h3 id=&quot;cEpc&quot;&gt;UI-тесты&lt;/h3&gt;
  &lt;p id=&quot;xO1G&quot;&gt;Начинаем делать UI-тесты, у нас все получается. Да, они выполняются медленнее, чем UI-тесты, но они снижают нагрузку на тестировщиков (если они вообще были и тестировали что-то), уверенность в каждом релизе все выше и выше с повышением процента покрытия UI-тестами.&lt;/p&gt;
  &lt;p id=&quot;vvbU&quot;&gt;Но баги все еще возникают. Что дальше?&lt;/p&gt;
  &lt;h3 id=&quot;hsY5&quot;&gt;Больше тестов!&lt;/h3&gt;
  &lt;p id=&quot;pohu&quot;&gt;Делаем больше тестов, потому что всегда есть что-то, что можно протестировать. Без шуток. Интеграционные тесты, e2e тесты и прочие страшные названия видов тестов.&lt;/p&gt;
  &lt;h2 id=&quot;W02l&quot;&gt;Реальность&lt;/h2&gt;
  &lt;p id=&quot;XTRx&quot;&gt;Выходит новая версия iOS/Android, в которой к чертям ломают что-то давно и стабильно работающее, или просто добавляют что-то новое, что вызывает краш в любом приложении или ломает клавиатуру/модальные окна, да что-угодно.&lt;/p&gt;
  &lt;p id=&quot;5tsu&quot;&gt;Выходит новая модель смартфона, на которой не протестировали базовый набор функционала, или на рынке появляется новая оболочка для андроида, которую вообще нафиг не тестировали, и что-то точно ломается. Прямо в проде, прямо в классном приложении, которое протестировано, и вообще не содержит легаси, да в нем вообще может быть один экран.&lt;/p&gt;
  &lt;p id=&quot;dPTa&quot;&gt;Выходит новый закон или пакет санкций и часть функционала отваливается у части пользователей из-за ip-адреса и т.д.&lt;/p&gt;
  &lt;h2 id=&quot;KweA&quot;&gt;В чем же проблема?&lt;/h2&gt;
  &lt;p id=&quot;Go9H&quot;&gt;На мой взгляд тут комбинация факторов, главный из которых - &lt;strong&gt;человеческий&lt;/strong&gt;, а потом все остальное, кому что больше нравится:&lt;/p&gt;
  &lt;ul id=&quot;svx6&quot;&gt;
    &lt;li id=&quot;nN5k&quot;&gt;угнаться за прибылью&lt;/li&gt;
    &lt;li id=&quot;1o11&quot;&gt;не отстать от конкурентов&lt;/li&gt;
    &lt;li id=&quot;ying&quot;&gt;попытаться повторить успешный сценарий, который у кого-то на рынке сработал&lt;/li&gt;
    &lt;li id=&quot;hvic&quot;&gt;и т.д.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;Ppl3&quot;&gt;Человеческий фактор&lt;/h3&gt;
  &lt;p id=&quot;PNNa&quot;&gt;Перечислю реальные случаи из моего опыта (без имен и компаний), потому что на мой взгляд это отличные примеры:&lt;/p&gt;
  &lt;ul id=&quot;qXl5&quot;&gt;
    &lt;li id=&quot;jlZg&quot;&gt;Можно не передавать задачу в тестирование, потому что вряд ли что-то сломается, там ведь так много легаси, и оно как-то работает, верно? Да и тестировать сейчас некому, а задача срочная...&lt;/li&gt;
    &lt;li id=&quot;D9JZ&quot;&gt;Можно не передавать в тестирование задачу, потому что разработчик проверяет ее сам, и уверен, что все будет хорошо, а если вдруг на регрессе найдут проблему, то ее будет несложно поправить&lt;/li&gt;
    &lt;li id=&quot;yFId&quot;&gt;Можно пройтись по сценарию тестирования вручную целиком, а можно не целиком, ведь вряд ли что-то сломалось в том месте, где мы даже не задевали в этом релизе?&lt;/li&gt;
    &lt;li id=&quot;Sdrf&quot;&gt;Можно пройтись по всем сценариям тестирования, найди баги, но посчитать их некритичными и никому не сообщить о них.&lt;/li&gt;
    &lt;li id=&quot;CdCh&quot;&gt;Можно пройтись по всем сценариям тестирования, найти баги и завести их в список багов, но не акцентировать внимание ни на одном из них, т.е. не высказать свое мнение в команде, потому что, очевидно, баги есть баги, и их когда-нибудь нужно будет починить, верно?&lt;/li&gt;
    &lt;li id=&quot;rVIf&quot;&gt;Можно пройтись по всем сценариям тестирования, рассказать всем про статус основных задач, и случайно найти другой баг, не относящийся к задачам, которые были в сценарии, и никому не сказать, потому что очевидно это старый баг, или баг другой команды, или его вообще не нужно было тестировать.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;SjrP&quot;&gt;Обстоятельства непреодолимой силы&lt;/h3&gt;
  &lt;p id=&quot;5JgO&quot;&gt;Выпуск новой версии системы, новой модели девайса, публикация нового закона - все эти факторы невозможно законтрить целиком, но можно хотя бы &amp;quot;подстелить подушку безопасности&amp;quot;, хотя бы показать нормальный текст ошибки, если это в вашей власти.&lt;/p&gt;
  &lt;p id=&quot;mczM&quot;&gt;Такие обстоятельства будут, на них нужно вовремя реагировать ... и по возможности покрывать такие сценарии автотестами 😉&lt;/p&gt;
  &lt;h2 id=&quot;rTpx&quot;&gt;Что же делать?&lt;/h2&gt;
  &lt;p id=&quot;HZpb&quot;&gt;На мой взгляд нужно включать критическое мышление как можно чаще, и анализировать ситуацию с точки зрения пользователя.&lt;/p&gt;
  &lt;p id=&quot;MDOK&quot;&gt;Можно поставить себя на место пользователя вашего приложения и прикинуть, насколько комфортно вам лично пользоваться приложением с багами, которые в нем есть. &lt;/p&gt;
  &lt;p id=&quot;vaom&quot;&gt;Нужно спросить себя/команду, можно ли как-то улучшить UX путем написания тестов, добавления дополнительных сценариев в общий список тестов и т.д.&lt;/p&gt;
  &lt;p id=&quot;3mrw&quot;&gt;В конце-концов можно автоматизировать многое, если есть желание, и пользователю будет приятнее.&lt;/p&gt;
  &lt;p id=&quot;fDnK&quot;&gt;И даже если пользователь не поставит 5 звезд в магазине приложений, даже если он не напишет вам благодарственное письмо - главное, что ему не приходится сталкиваться с багами, которые было легко поймать до релиза.&lt;/p&gt;
  &lt;h2 id=&quot;Fspu&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;GKLM&quot;&gt;Спасают ли тесты от багов? Нет.&lt;/p&gt;
  &lt;p id=&quot;NWxg&quot;&gt;Нужны ли тесты? Обязательно, если вам важен &lt;strong&gt;качественный&lt;/strong&gt; результат ✅&lt;/p&gt;

</content></entry><entry><id>easy_dev991:ldaAHhOaDJG</id><link rel="alternate" type="text/html" href="https://teletype.in/@easy_dev991/ldaAHhOaDJG?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=easy_dev991"></link><title>Как я выбирал андроид-смартфон</title><published>2026-07-28T10:47:56.456Z</published><updated>2026-07-28T10:47:56.456Z</updated><category term="android" label="Android"></category><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/6e/9b/6e9bdbbb-1202-4434-ae31-de99b6bdeb6b.jpeg&quot;&gt;В предыдущей статье рассказал про свой переход с iOS на Android. В этой расскажу как выбирал смартфон, и что в итоге выбрал.</summary><content type="html">
  &lt;p id=&quot;e1Ym&quot;&gt;В &lt;a href=&quot;https://teletype.in/@easy_dev991/nQFonqU59Zp&quot; target=&quot;_blank&quot;&gt;предыдущей статье&lt;/a&gt; рассказал про свой переход с iOS на Android. В этой расскажу как выбирал смартфон, и что в итоге выбрал.&lt;/p&gt;
  &lt;h2 id=&quot;IhJH&quot;&gt;Критерии&lt;/h2&gt;
  &lt;h3 id=&quot;VLBo&quot;&gt;Вспомним iPhone&lt;/h3&gt;
  &lt;p id=&quot;m85a&quot;&gt;Пользователь айфона объективно не может иметь большого набора критериев для выбора девайса, потому что айфоны есть всего нескольких типов (раскладушку не считаем, т.к. пока не было релиза):&lt;/p&gt;
  &lt;ul id=&quot;iYi8&quot;&gt;
    &lt;li id=&quot;l5cz&quot;&gt;Маленький (SE/mini)&lt;/li&gt;
    &lt;li id=&quot;vCax&quot;&gt;Стандартный&lt;/li&gt;
    &lt;li id=&quot;sb0p&quot;&gt;Pro&lt;/li&gt;
    &lt;li id=&quot;GRNb&quot;&gt;Pro Max&lt;/li&gt;
    &lt;li id=&quot;mzYW&quot;&gt;Air&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;vYAD&quot;&gt;На каждой модели будет одна и та же версия системы (iOS), с примерно одинаковым набором багов.&lt;/p&gt;
  &lt;h3 id=&quot;RYdv&quot;&gt;Теперь Android&lt;/h3&gt;
  &lt;p id=&quot;kRKw&quot;&gt;Поскольку производителей смартфонов на андроиде просто дофига, то можно выбирать из большого перечня параметров. Вот мои основные критерии:&lt;/p&gt;
  &lt;ul id=&quot;BXfD&quot;&gt;
    &lt;li id=&quot;9Tqq&quot;&gt;Легкий вес - желательно намного меньше 204гр (мой старый iPhone 13 Pro), потому что не люблю держать в руках тяжелые девайсы (все еще жду макбук про на 16 дюймов весом меньше 2кг) &lt;/li&gt;
    &lt;li id=&quot;VefW&quot;&gt;Нормальный сканер пальцев - не оптический, а ультразвуковой, чтобы мокрые пальцы тоже распознавал (хотя любой сканер пальца все равно хуже, чем Face Unlock в iOS)&lt;/li&gt;
    &lt;li id=&quot;LQOm&quot;&gt;Постоянная память не меньше 256гб&lt;/li&gt;
    &lt;li id=&quot;1vMn&quot;&gt;Защита не ниже iP68 (кому нужно, чтобы под дождем телефон загнулся?)&lt;/li&gt;
    &lt;li id=&quot;U4RR&quot;&gt;OLED-экран 120гц с поддержкой LTPO&lt;/li&gt;
    &lt;li id=&quot;KJ2n&quot;&gt;Экран с диагональю не больше 6.3 дюймов&lt;/li&gt;
    &lt;li id=&quot;00ZX&quot;&gt;Операционная система без рекламы и софта, который нельзя отключить/убрать&lt;/li&gt;
    &lt;li id=&quot;75Dc&quot;&gt;Хорошая автономность - не меньше двух дней при моем обычном сценарии использования&lt;/li&gt;
    &lt;li id=&quot;5XR8&quot;&gt;Корпус без гигантских шайб и прочих хитровыпендренных штук&lt;/li&gt;
    &lt;li id=&quot;Gpem&quot;&gt;Поддержка ESIM&lt;/li&gt;
    &lt;li id=&quot;cFSm&quot;&gt;Возможность выбрать цвет корпуса кроме черного/белого (не пользуюсь чехлами для телефона)&lt;/li&gt;
    &lt;li id=&quot;H1Mc&quot;&gt;Было бы неплохо иметь макро-камеру и оптический зум&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;MbvE&quot;&gt;С критериями определились (всего-то, да?).&lt;/p&gt;
  &lt;h2 id=&quot;gNin&quot;&gt;Варианты&lt;/h2&gt;
  &lt;p id=&quot;mgd1&quot;&gt;Я нашел несколько вариантов, которые по характеристикам меня устраивали:&lt;/p&gt;
  &lt;ul id=&quot;IlK2&quot;&gt;
    &lt;li id=&quot;bR5K&quot;&gt;Motorola Edge 60 Neo (не нашел в продаже)&lt;/li&gt;
    &lt;li id=&quot;Lv9x&quot;&gt;OnePlus 13s (тяжеловат)&lt;/li&gt;
    &lt;li id=&quot;Izdx&quot;&gt;Samsung Galaxy S24/S25/S26&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;76EX&quot;&gt;Решил выбирать из самсунгов, потому что по основным моим критериям они прошли.&lt;/p&gt;
  &lt;h3 id=&quot;W5Kk&quot;&gt;Выбираю из самсунгов&lt;/h3&gt;
  &lt;p id=&quot;GP9C&quot;&gt;Выбор оказался не таким сложным, как я изначально ожидал.&lt;/p&gt;
  &lt;p id=&quot;EOsp&quot;&gt;Немного почитав в интернетах (и посмотрев обзоры), узнал, что самсунг (прямо как эпол) штампует одинаковые девайсы каждый год, которые почти ничем не отличаются друг от друга. Однако в отличие от эпол, стоимость самсунгов снижается чуть сильнее из года в год.&lt;/p&gt;
  &lt;p id=&quot;2eHR&quot;&gt;Внимательно сравнив S24/S25/S26 можно прийти к выводу, что разницы между ними почти нет, и так и есть на самом деле.&lt;/p&gt;
  &lt;p id=&quot;Dif8&quot;&gt;Переплачивать за самый новый S26 не было смысла, а в S25 аккумулятор чуть более емкий, чем в S24, поэтому взял S25.&lt;/p&gt;
  &lt;figure id=&quot;e93N&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6e/9b/6e9bdbbb-1202-4434-ae31-de99b6bdeb6b.jpeg&quot; width=&quot;1080&quot; /&gt;
    &lt;figcaption&gt;В среднем 26% заряда трачу в день, это примерно 1.5 часа времени с включенным экраном, S25 отлично держит 3 дня с запасом в моем обычном режиме использования&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;xnH0&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;aYrX&quot;&gt;Кто бы мог подумать, что при покупке смартфона на андроиде нужной модели может просто не оказаться ни в одном магазине, даже если релиз состоялся в прошлом году? А вот так оно и есть 🙂&lt;/p&gt;

</content></entry><entry><id>easy_dev991:nQFonqU59Zp</id><link rel="alternate" type="text/html" href="https://teletype.in/@easy_dev991/nQFonqU59Zp?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=easy_dev991"></link><title>Переход с iOS на Android</title><published>2026-07-21T18:19:17.450Z</published><updated>2026-07-21T18:19:30.754Z</updated><category term="android" label="Android"></category><summary type="html">Месяц назад я сменил основной смартфон на андроид, и сейчас расскажу почему и как все прошло.</summary><content type="html">
  &lt;p id=&quot;QEFI&quot;&gt;Месяц назад я сменил основной смартфон на андроид, и сейчас расскажу почему и как все прошло.&lt;/p&gt;
  &lt;h2 id=&quot;sZcb&quot;&gt;Без паники!&lt;/h2&gt;
  &lt;p id=&quot;MNFw&quot;&gt;Для начала успокою своих самых преданных подписчиков: айфон у меня все еще есть - использую его для рабочих задач:&lt;/p&gt;
  &lt;ul id=&quot;Z2Qp&quot;&gt;
    &lt;li id=&quot;Q2sg&quot;&gt;проверить фичу на сборке из testflight (ручное тестирование)&lt;/li&gt;
    &lt;li id=&quot;WTKh&quot;&gt;задебажить хитрый сценарий, который возникает на девайсе, но не на симуляторе (по проводу в Xcode)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;zK98&quot;&gt;Причины для перехода&lt;/h2&gt;
  &lt;h3 id=&quot;AFn7&quot;&gt;Процесс публикации своих приложений&lt;/h3&gt;
  &lt;p id=&quot;FbOP&quot;&gt;Я хотел делать приложения, которыми будет приятно пользоваться, и делиться ими с другими людьми, но недавно закрыли последнюю официальную &amp;quot;лавочку&amp;quot; для оплаты подписки разработчика apple, а без этого невозможно опубликовать приложения для iOS во всеми любимом AppStore.&lt;/p&gt;
  &lt;p id=&quot;5hs0&quot;&gt;Теперь нельзя оплатить аккаунт со счета оператора связи, а искать новые обходные пути (менять регион аккаунта и т.д.) мне не хочется - я ведь не огромная компания с кучей платных подписчиков или постоянным притоком денег.&lt;/p&gt;
  &lt;p id=&quot;xQ6d&quot;&gt;Мне нравилось пользоваться своими приложениями на айфоне - это правда, но мне совершенно не нравилось публиковать свои приложения в аппсторе, потому что это та еще цирковая передача.&lt;/p&gt;
  &lt;p id=&quot;OTnT&quot;&gt;Тем, кто не публиковал приложения сам, или кто публиковал только несколько сборок, наверное сложно будет представить как это происходит.&lt;/p&gt;
  &lt;p id=&quot;a8dE&quot;&gt;&lt;strong&gt;Вкратце процесс выглядит так&lt;/strong&gt;:&lt;/p&gt;
  &lt;ul id=&quot;AaFd&quot;&gt;
    &lt;li id=&quot;BaQ8&quot;&gt;регистрируешься в качестве разработчика apple&lt;/li&gt;
    &lt;li id=&quot;gi8R&quot;&gt;(делаешь само приложение, что обычно не очень сложно и довольно интересно)&lt;/li&gt;
    &lt;li id=&quot;4PRU&quot;&gt;находишь способ оплатить подписку (8990 р/год) - да, не у всех и не с первого раза получалось ее оплатить, и если вы физ.лицо, то никаких встроенных покупок у вас в приложении не будет&lt;/li&gt;
    &lt;li id=&quot;1exN&quot;&gt;заполняешь тонну полей в анкете для создания каждого приложения&lt;/li&gt;
    &lt;li id=&quot;42YQ&quot;&gt;загружаешь приложение в кабинет разработчика&lt;/li&gt;
    &lt;li id=&quot;ORM0&quot;&gt;отправляешь на модерацию&lt;/li&gt;
    &lt;li id=&quot;vwrt&quot;&gt;надеешься, что попадется не стремный модератор&lt;/li&gt;
    &lt;li id=&quot;SBms&quot;&gt;попадается стремный модератор с идиотскими вопросами, ответы на которые есть буквально в той же самой анкете, которую ты уже заполнял ранее&lt;/li&gt;
    &lt;li id=&quot;e6v4&quot;&gt;отвечаешь на все вопросы и ждешь, пока модератор соизволит одобрить приложение или задаст еще какие-нибудь идиотские вопросы&lt;/li&gt;
    &lt;li id=&quot;AKgm&quot;&gt;в случае успешной проверки приложение через некоторое время появляется в магазине ... или не появляется несколько часов без объяснения причин, или через пару дней появится, ну как повезет&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;bHbJ&quot;&gt;И в целом даже с таким стремным процессом (оформление приложения в кабинете apple, модерация) я готов был мириться, пока схема работала хотя бы в таком виде.&lt;/p&gt;
  &lt;h3 id=&quot;0P3k&quot;&gt;Санкции&lt;/h3&gt;
  &lt;p id=&quot;kKYQ&quot;&gt;Бац - удалили банковские приложения. Бац - удалили еще пачку приложений.&lt;/p&gt;
  &lt;p id=&quot;uqj8&quot;&gt;Просто потому что политика, отлично.&lt;/p&gt;
  &lt;p id=&quot;UzJH&quot;&gt;Я конечно поразвлекался, пока загружал приложения от крупных компаний через их обходные пути, в том числе приложение &lt;strong&gt;РЖД&lt;/strong&gt;, которое они распространяют через &lt;strong&gt;Testflight&lt;/strong&gt; для обычных пользователей (ни в какие ворота, ну камон), но надоело.&lt;/p&gt;
  &lt;p id=&quot;r0UU&quot;&gt;Еще просидел около 40 минут в зеленом банке, пока сотрудник банка с тупым взглядом пытался установить мне приложение, и нифига не получилось. &lt;/p&gt;
  &lt;p id=&quot;q5qQ&quot;&gt;Справедливости ради, за неделю до перехода на андроид мне все же удалось в другом офисе этого банка установить приложение, считаю это невероятным везением.&lt;/p&gt;
  &lt;h3 id=&quot;b2Ud&quot;&gt;Операционная система&lt;/h3&gt;
  &lt;p id=&quot;RTsu&quot;&gt;iOS уже не тот. Даже если эта фраза выглядит избитой, то сейчас я для себя это ощутил сполна, когда перешел на iOS 26.&lt;/p&gt;
  &lt;p id=&quot;xhBO&quot;&gt;Да, стекло не каждому нравится, ну и фиг с ним, но зависания на домашнем экране, глюки анимации и прочие проблемы, которые раньше у меня ассоциировались с дешевыми смартфонами на андроиде - это неприемлемо.&lt;/p&gt;
  &lt;p id=&quot;MZDk&quot;&gt;Мои требования к айфону стали слишком высокими, потому что я отлично помню iPhone 5s, который классно работал, и не лагал как iPhone 13 Pro.&lt;/p&gt;
  &lt;p id=&quot;JL4y&quot;&gt;Причем ошибки и тормоза каждый год добавляются поверх старых, как будто так и должно быть, как будто пользователи (в том числе я) должны просто это терпеть - ну нафиг. Забегая вперед - если так и дальше продлится, и если даже андроидом будет невозможно пользоваться, куплю кнопочный телефон. Скриньте.&lt;/p&gt;
  &lt;p id=&quot;qz5q&quot;&gt;Представьте себе, перенести данные с айфона на айфон мне удалось не с первого раза, когда недавно менял айфон.&lt;/p&gt;
  &lt;p id=&quot;mve1&quot;&gt;Руки кривые? Да, но не у меня, а у тех умников, которые пропустили iOS 26 в продакшен и забили на ручное тестирование (по всей видимости, уже очень давно).&lt;/p&gt;
  &lt;h2 id=&quot;r9vk&quot;&gt;Месяц на андроиде&lt;/h2&gt;
  &lt;p id=&quot;32ME&quot;&gt;Процесс переноса данных с айфона на андроид оказался ничем не хуже, чем перенос данных со старого айфона на новый - удалось все перенести со второй попытки (для такой же процедуры с двумя айфонами на iOS 26 пришлось потратить 3 попытки).&lt;/p&gt;
  &lt;h3 id=&quot;gm7H&quot;&gt;Что не понравилось&lt;/h3&gt;
  &lt;p id=&quot;ViJo&quot;&gt;&lt;strong&gt;Сканер отпечатка пальцев&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;Vyqy&quot;&gt;В моем смартфоне ультразвуковой сканер пальца, и это полный отстой по сравнению с face id в айфоне (а ведь еще бывают и оптические сканеры пальца, жуть). Нужно попасть в конкретную зону экрана пальцем, при этом регулярно палец не распознается даже с трех раз. В этом плане пока что андроиды сильно проигрывают айфонам (хотя есть новости о предстоящем добавлении аналога face id, но это где-то в будущем).&lt;/p&gt;
  &lt;p id=&quot;WMYD&quot;&gt;&lt;strong&gt;Системные приложения и баги&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;9r2Y&quot;&gt;Скорее всего привычка к iOS все еще сказывается - просто не хватает некоторых мелочей, которые были удобны в iOS.&lt;/p&gt;
  &lt;p id=&quot;XYIg&quot;&gt;Например, галерея не индексирует фотографии без особых настроек девайса. Через 2 недели после покупки я загуглил как это поправить и за 2 ночи все фото/видео проиндексировались, но некоторые отметили людей с ошибками, а исправить эти ошибки буквально нельзя в стандартном приложении галереи (гугл фото не использую).&lt;/p&gt;
  &lt;p id=&quot;7ERF&quot;&gt;Темная тема не включается/выключается по расписанию при смене режима на &amp;quot;сон&amp;quot; и обратно, что является частой проблемой в купленном мной андроиде, и прочие мелкие проблемы.&lt;/p&gt;
  &lt;h3 id=&quot;PcIR&quot;&gt;Что понравилось&lt;/h3&gt;
  &lt;p id=&quot;jnhG&quot;&gt;&lt;strong&gt;Публикация своих приложений&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;uJyG&quot;&gt;Помните ту дикую инструкцию в самом начале статьи для публикации в аппсторе на iOS?&lt;/p&gt;
  &lt;p id=&quot;n9k7&quot;&gt;Тут шагов всего 2: &lt;/p&gt;
  &lt;ul id=&quot;Q9oK&quot;&gt;
    &lt;li id=&quot;qVmi&quot;&gt;сделать приложение (спасибо агентам за удобство и скорость в этом деле)&lt;/li&gt;
    &lt;li id=&quot;aFse&quot;&gt;установить себе на девайс (и при желании поделиться со всем интернетом)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;jyj3&quot;&gt;Шок-контент!&lt;/p&gt;
  &lt;p id=&quot;Yb8U&quot;&gt;Я и раньше знал об этом, но пока лично не попробовал, не думал, что это настолько удобно.&lt;/p&gt;
  &lt;p id=&quot;slFr&quot;&gt;Да, система не дает устанавливать приложения не из магазина по умолчанию, но это можно обойти за пару секунд, с помощью системных настроек в разделе &amp;quot;Безопасность&amp;quot;.&lt;/p&gt;
  &lt;p id=&quot;E4XM&quot;&gt;Еще удобно публиковать свои приложения в rustore, хотя сам я его не скачал, но мои приложения там есть, и одно из них регулярно скачивают.&lt;/p&gt;
  &lt;p id=&quot;gg46&quot;&gt;&lt;strong&gt;Сторонние магазины приложений&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;wyIv&quot;&gt;Я использую f-droid и repostore, и мне очень нравится! &lt;/p&gt;
  &lt;p id=&quot;c5tH&quot;&gt;Например, стандартный ютуб мне не нравится ни в iOS, ни в Android, поэтому я установил другое приложение из гитхаба через repostore, которое мне нравится намного больше, чем официальное от гугла.&lt;/p&gt;
  &lt;p id=&quot;aWgV&quot;&gt;Да, я знаю про риски, и да, я несу ответственность за установку таких приложений сам. Но как будто в гугл-магазине и аппсторе никогда не было мошеннических приложений?&lt;/p&gt;
  &lt;h3 id=&quot;SJX3&quot;&gt;Автоматизация&lt;/h3&gt;
  &lt;p id=&quot;S6tD&quot;&gt;У меня в айфоне были 2 &amp;quot;быстрые команды&amp;quot;, которые активировались либо голосом (как и любая быстрая команда) через Siri, либо нажатием на ярлык на рабочем столе:&lt;/p&gt;
  &lt;ul id=&quot;VMaP&quot;&gt;
    &lt;li id=&quot;RhcZ&quot;&gt;выхожу из дома (для включения блютус + lte, и выключения wifi)&lt;/li&gt;
    &lt;li id=&quot;XM5m&quot;&gt;вернулся домой (обратный процесс)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;AKMR&quot;&gt;В андроиде эти две команды включаются автоматически без необходимости нажимать на ярлык или выполнять голосовую команду, и это БЕЗ использования геолокации, чудеса!&lt;/p&gt;
  &lt;p id=&quot;UTWs&quot;&gt;Самое классное то, что настроить это можно было без хитровыпендренных завихрений приложения &amp;quot;Команды&amp;quot; (iOS), в котором черт ногу сломит (ну серьезно, никогда не любил процесс создания команд, но полезные команды там все же можно сделать) - просто в системных настройках есть раздел &amp;quot;Режимы и сценарии&amp;quot;, где можно добавлять любые сценарии и делать это с намного более удобным UX.&lt;/p&gt;
  &lt;h2 id=&quot;sOfg&quot;&gt;А что с карьерой?&lt;/h2&gt;
  &lt;p id=&quot;DLfw&quot;&gt;Делать приложения для себя - одно, а работать iOS-разработчиком - совсем другое дело. Я все еще считаю, что было отличным (и удачным) решением научиться этому делу и зайти в эту профессию до активного развития нейросетей.&lt;/p&gt;
  &lt;h2 id=&quot;coBG&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;SeZc&quot;&gt;Да, я знаю про предстоящие изменения в политике гугла и надвигающихся осложнениях в установке приложений не из магазина гугла, но что поделать - будем адаптироваться. В любом случае есть еще PWA, так что не пропадем 😅&lt;/p&gt;
  &lt;p id=&quot;90nC&quot;&gt;Если статья соберет больше 5 лайков, расскажу про критерии, по которым я выбирал себе смартфон на андроиде, и что в итоге выбрал ✅&lt;/p&gt;

</content></entry><entry><id>easy_dev991:G6cggxnKUec</id><link rel="alternate" type="text/html" href="https://teletype.in/@easy_dev991/G6cggxnKUec?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=easy_dev991"></link><title>Краткий обзор ponytail</title><published>2026-07-12T13:00:08.746Z</published><updated>2026-07-12T13:00:29.454Z</updated><category term="agent" label="agent"></category><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/47/38/47386765-bc56-4397-b3fc-07fcb32800bf.png&quot;&gt;Уже больше недели использую ponytail на постоянной основе в opencode, и мне нравятся результаты.</summary><content type="html">
  &lt;p id=&quot;crRe&quot;&gt;Уже больше недели использую &lt;a href=&quot;https://github.com/DietrichGebert/ponytail&quot; target=&quot;_blank&quot;&gt;ponytail&lt;/a&gt; на постоянной основе в &lt;code&gt;opencode&lt;/code&gt;, и мне нравятся результаты.&lt;/p&gt;
  &lt;h2 id=&quot;NNa6&quot;&gt;Как это работает&lt;/h2&gt;
  &lt;p id=&quot;RvDQ&quot;&gt;Предлагаю прочитать &lt;a href=&quot;https://github.com/DietrichGebert/ponytail/blob/main/README.md&quot; target=&quot;_blank&quot;&gt;ридми&lt;/a&gt; - там есть достаточное количество примеров и описание этого инструмента, а сюда просто скопирую оттуда кусочек:&lt;/p&gt;
  &lt;figure id=&quot;cX1T&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/47/38/47386765-bc56-4397-b3fc-07fcb32800bf.png&quot; width=&quot;962&quot; /&gt;
    &lt;figcaption&gt;Перед тем как написать код, агент проводит такой анализ (скриншот из ридми)&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;mCFQ&quot;&gt;Как я это использую&lt;/h2&gt;
  &lt;h3 id=&quot;gQ7F&quot;&gt;Сценарий 1&lt;/h3&gt;
  &lt;p id=&quot;QDyM&quot;&gt;В пет-проектах, над которыми давно не работал, использую основную команду &lt;code&gt;/ponytail-audit&lt;/code&gt; - эта команда проверяет весь репозиторий, например, проверим &lt;a href=&quot;https://github.com/easydev991/SwiftUI-Days&quot; target=&quot;_blank&quot;&gt;SwiftUI-Days&lt;/a&gt;:&lt;/p&gt;
  &lt;pre id=&quot;MV4N&quot;&gt;Now I have a complete picture of the entire codebase. Here&amp;#x27;s the audit:
yagni ItemSchema.swift + ItemMigrationPlan.swift (157 lines). Three versioned schemas duplicating the model + two custom migration stages that only set optional fields to nil. SwiftData lightweight migration handles this automatically when you just add optional properties. SwiftUI-Days/Models/ItemSchema.swift, SwiftUI-Days/Models/ItemMigrationPlan.swift
shrink BackupFileDocument.swift (217 lines). RawBackupItem duplicates BackupItem with different encode/decode strategy — same 5 fields, two Codable impls. BackupWrapper envelope format + legacy flat array = two parsing paths for one export format. Merge into a single type, drop the legacy path. SwiftUI-Days/Models/BackupFileDocument.swift
yagni Analytics — 4 files (AnalyticsProvider protocol + FirebaseAnalyticsProvider + NoopAnalyticsProvider + AnalyticsService) for one real provider. The protocol has one method and one implementation in production. A single AnalyticsService with a Firebase-only init (or a log closure parameter) replaces 4 files. SwiftUI-Days/Services/Analytics/
yagni SectionTitleView.swift (35 lines). A .bold().foregroundStyle(isEnabled ? .primary : .secondary).frame(maxWidth: .infinity, alignment: .leading) modifier on Text. That&amp;#x27;s a one-line View extension, not a file. SwiftUI-Days/Screens/CommonViews/SectionTitleView.swift
yagni EditSectionView.swift (30 lines). Used in one screen (EditItemScreen). Inline the SectionTitleView + TextField pair. SwiftUI-Days/Screens/Detail/EditSectionView.swift
yagni ReadSectionView.swift (33 lines). Used in one screen (ItemScreen). Inline the SectionTitleView + Text pair. SwiftUI-Days/Screens/Detail/ReadSectionView.swift
yagni DaysEditButton.swift (13 lines). Button { action } Label(.edit, systemImage: &amp;quot;pencil&amp;quot;). Used in two places; inline Button directly is less code than the file overhead. SwiftUI-Days/Screens/Main/DaysEditButton.swift
yagni DaysDeleteButton.swift (19 lines). Same as DaysEditButton. SwiftUI-Days/Screens/Main/DaysDeleteButton.swift
yagni ItemDatePicker.swift (14 lines). A DatePicker with .bold(). Inline. SwiftUI-Days/Screens/Detail/ItemDatePicker.swift
yagni ItemDisplayOptionPicker.swift (24 lines). A Picker with SectionTitleView. Used in two screens; inline both calls. SwiftUI-Days/Screens/Detail/ItemDisplayOptionPicker.swift
yagni ColorTagFilterSheetState.swift (36 lines). Compute-only struct used by one sheet. The three computed properties + two methods can live in the sheet body. SwiftUI-Days/Screens/Main/ColorTagFilterSheetState.swift
yagni Binding+mappedToBool.swift (21 lines). Single-use extension. Inline init(bindingOptional:) at the call site in AppDataScreen. SwiftUI-Days/Extensions/Binding+mappedToBool.swift
yagni ThemeIconScreen+IconViewModel.swift IconError (10 lines). Single-case error enum. Use a descriptive string instead. SwiftUI-Days/Screens/More/ThemeIcon/ThemeIconScreen+IconViewModel.swift
delete BackupFormat.android case. iOS-only app. SwiftUI-Days/Models/BackupFormat.swift
delete AppDataError.swift (5 lines). Single-case enum used once. Use a string literal. SwiftUI-Days/Models/AppDataError.swift
delete ColorTagFilterSheet+Preview.swift (31 lines). 10 static let constants configuring hue/saturation/brightness/count for previews. The previews call static constants that equal literal numbers — use the numbers directly. SwiftUI-Days/Preview Content/ColorTagFilterSheet+Preview.swift
stdlib Color+Hex.swift body (51 lines discounting preview). Hand-rolled hex-to-UInt64 scanner. Scanner already does scanHexInt64. The bit-shifting color extraction is just CGFloat math that UIColor component accessor already provides. Could halve the line count. SwiftUI-Days/Extensions/Color+Hex.swift
shrink DisplayOption.unitsStyle (20 lines). Switch-picking .full/.short/.abbreviated based on which components are nonzero. This is polish: DateComponentsFormatter auto-selects a reasonable style. SwiftUI-Days/Models/DisplayOption.swift
shrink Item.makeDaysCount creates a new DateComponentsFormatter per call. A static let formatter saves the allocation. SwiftUI-Days/Models/Item.swift
shrink FeedbackSender.platformName — nested function inside a computed var body. Extract or inline. SwiftUI-Days/Services/FeedbackSender.swift
yagni ThemeIconScreen+IconVariant.variantNumber — manual switch self returning 1...7. A @frozen enum with Int raw value gives this for free. SwiftUI-Days/Screens/More/ThemeIcon/ThemeIconScreen+IconVariant.swift
net: -~660 lines, -1 dependency (Firebase could go closure-based but kept), -1 file (BackupFormat.android dead path)&lt;/pre&gt;
  &lt;p id=&quot;VcVR&quot;&gt;Дальше закидываю этот анализ в другую модель и прошу составить план безопасного рефактора, чтобы ничего не сломать.&lt;/p&gt;
  &lt;h3 id=&quot;ZAhs&quot;&gt;Сценарий 2&lt;/h3&gt;
  &lt;p id=&quot;4lxk&quot;&gt;В процессе работы проверяю конкретный коммит с помощью команды &lt;code&gt;/ponytail-review&lt;/code&gt;, например:&lt;/p&gt;
  &lt;p id=&quot;oWhI&quot;&gt;&lt;code&gt;/ponytail-review коммит 8e82b6cad16c12c1dcca1574b6908304ef15ccc8&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;UbDx&quot;&gt;В результате получаю похожий отчет, с которым потом можно работать дальше:&lt;/p&gt;
  &lt;pre id=&quot;hJVs&quot;&gt;Ponytail review — коммит 8e82b6ca
Ниже только over-engineering, не correctness.
- ColorTagFilterSheetState.swift:1 yagni Целая структура + enum для двух if-else (applyEnabled/resetEnabled/toggledColorHex/resetResult). Всё в 4 строчки в теле view. Удалить файл.
- MainScreenFilterState.swift:11 shrink itemsCountForFilterButton — синоним visibleItems.count. Убрать, заменить на visibleItems.count в isFilterButtonVisible.
- ColorTagFilterSheet+Preview.swift:9 yagni colors1 = 1, colors3 = 3, colors8 = 8, colors30 = 30 — константы, равные числу. Лишние имена. Вставить числа в вызовы.
- docs/doc-main-screen-color-tag-filter.md:1 yagni 78 строк внутренней документации, которая устареет при следующем рефакторинге. Удалить, пока не появился внешний контрибьютор, которому она нужна.
Net removable: ~40 строк&lt;/pre&gt;
  &lt;h2 id=&quot;3n8o&quot;&gt;Что с рабочим проектом&lt;/h2&gt;
  &lt;p id=&quot;IELI&quot;&gt;Если запустить аудит всего рабочего проекта, то агент предлагает поудалять много нужного кода и зависимостей, поэтому не рекомендую запускать аудит большого проекта целиком. Во всяком случае недорогие модели с такой задачей справляются плохо.&lt;/p&gt;
  &lt;p id=&quot;1cqH&quot;&gt;При этом польза ощутима при выполнении конкретных задач, когда срабатывает проверка на YAGNI из раздела &amp;quot;Как это работает&amp;quot;, и получается меньше кода, чем могло бы быть без этих проверок.&lt;/p&gt;
  &lt;h2 id=&quot;kyri&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;wP8J&quot;&gt;Это уже &lt;strong&gt;пятый&lt;/strong&gt; инструмент для агентов, который я использую на постоянной основе внутри &lt;code&gt;opencode&lt;/code&gt;, а полный список вот: &lt;code&gt;serena&lt;/code&gt;, &lt;code&gt;codegraph&lt;/code&gt;, &lt;code&gt;rtk&lt;/code&gt;, &lt;code&gt;openspec&lt;/code&gt;, &lt;code&gt;ponytail&lt;/code&gt;, и все складывается очень даже удобно для работы с агентом 👍&lt;/p&gt;

</content></entry><entry><id>easy_dev991:2BqBJC8Wrkh</id><link rel="alternate" type="text/html" href="https://teletype.in/@easy_dev991/2BqBJC8Wrkh?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=easy_dev991"></link><title>Экспорт напоминаний Apple</title><published>2026-07-05T10:10:11.486Z</published><updated>2026-07-05T10:35:13.854Z</updated><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/a3/8a/a38a06a6-ddf0-489b-97e4-2677937971cf.png&quot;&gt;Недавно перешел с ios на андроид и захотел перенести все напоминания из стандартного приложения &quot;Напоминания&quot; на маке/айфоне, но не нашел простого способа как это сделать, поэтому сделал инструмент для экспорта напоминаний.</summary><content type="html">
  &lt;p id=&quot;8g2t&quot;&gt;Недавно перешел с ios на андроид и захотел перенести все напоминания из стандартного приложения &amp;quot;Напоминания&amp;quot; на маке/айфоне, но не нашел простого способа как это сделать, поэтому сделал &lt;a href=&quot;https://github.com/easydev991/export-reminders-from-mac&quot; target=&quot;_blank&quot;&gt;инструмент для экспорта напоминаний&lt;/a&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;mdZD&quot;&gt;Проблема&lt;/h2&gt;
  &lt;p id=&quot;mP4l&quot;&gt;Есть несколько приложений в аппсторе, которые достают напоминания из стандартного приложения и что-то дальше с ними делают (чаще всего просто копируют их в себя).&lt;/p&gt;
  &lt;p id=&quot;83yD&quot;&gt;Однако эти приложения не позволяют бесплатно экспортировать список напоминаний, чтобы делать потом с ними что-то еще.&lt;/p&gt;
  &lt;p id=&quot;56P2&quot;&gt;Синхронизация между платформами тоже нетривиальная задача, и популярные приложения не дают бесплатно синхронизировать напоминания между платформами.&lt;/p&gt;
  &lt;p id=&quot;nb53&quot;&gt;Я даже поробовал microsoft todo, но мне совсем не понравилось их приложение.&lt;/p&gt;
  &lt;h2 id=&quot;RpRE&quot;&gt;Решение&lt;/h2&gt;
  &lt;p id=&quot;jJPW&quot;&gt;Нашел бесплатное и неплохое приложение для андроид &lt;a href=&quot;https://github.com/tasks/tasks&quot; target=&quot;_blank&quot;&gt;Tasks.org&lt;/a&gt;, и сделал небольшой инструмент на свифте для экспорта из приложения &amp;quot;Напоминания&amp;quot; на макбуке в формат &lt;strong&gt;Tasks.org&lt;/strong&gt;.&lt;/p&gt;
  &lt;p id=&quot;8rdp&quot;&gt;Разработку вел целиком с использованием &lt;code&gt;opencode&lt;/code&gt; + &lt;code&gt;openspec&lt;/code&gt; - рассказывал об этом подходе в &lt;a href=&quot;https://teletype.in/@easy_dev991/TQsjWIzfHde&quot; target=&quot;_blank&quot;&gt;предыдущей статье&lt;/a&gt;.&lt;/p&gt;
  &lt;figure id=&quot;igQ9&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/a3/8a/a38a06a6-ddf0-489b-97e4-2677937971cf.png&quot; width=&quot;1424&quot; /&gt;
    &lt;figcaption&gt;Доступные команды в Makefile на момент первого релиза&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;rRmV&quot;&gt;Как пользоваться&lt;/h3&gt;
  &lt;ol id=&quot;MbFh&quot;&gt;
    &lt;li id=&quot;uio8&quot;&gt;Клонировать репозиторий&lt;/li&gt;
    &lt;li id=&quot;kBkn&quot;&gt;Открыть терминал в папке проекта&lt;/li&gt;
    &lt;li id=&quot;g3cQ&quot;&gt;Выполнить команду &lt;code&gt;make export-tasks-org&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;3GTF&quot;&gt;Взять получившийся файл &lt;code&gt;reminders_export_tasks_org.json&lt;/code&gt; из папки с проектом и импортировать в андроид-приложение &lt;strong&gt;Tasks.org&lt;/strong&gt;&lt;/li&gt;
    &lt;li id=&quot;pAsn&quot;&gt;Профит&lt;/li&gt;
  &lt;/ol&gt;
  &lt;h2 id=&quot;DZQN&quot;&gt;Выводы&lt;/h2&gt;
  &lt;p id=&quot;7qM9&quot;&gt;Является ли это решение лучшим? Вряд ли. Единственным? Нет. При этом я сделал его довольно быстро, и было очень легко тестировать прямо на симуляторе в андроид-студии.&lt;/p&gt;
  &lt;p id=&quot;Anpp&quot;&gt;Нужны ли знания языка программирования для создания подобных инструментов? Точно нет.&lt;/p&gt;
  &lt;p id=&quot;0Uxk&quot;&gt;Удобно ли мне пользоваться приложением Tasks.org на андроиде? Вполне ✅&lt;/p&gt;
  &lt;p id=&quot;6peF&quot;&gt;Было ли удобнее в стандартном приложении &amp;quot;Напоминания&amp;quot; от apple? 💯 Да    &lt;/p&gt;

</content></entry><entry><id>easy_dev991:TQsjWIzfHde</id><link rel="alternate" type="text/html" href="https://teletype.in/@easy_dev991/TQsjWIzfHde?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=easy_dev991"></link><title>openspec в работе</title><published>2026-06-27T12:09:21.394Z</published><updated>2026-06-27T12:09:48.063Z</updated><category term="agent" label="agent"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/f1/5d/f15d7427-e310-4ff3-9992-d20d928d0596.png&quot;&gt;Примерно два месяца назад я узнал про openspec, и решил попробовать. Пет-проекты на тот момент были на паузе, поэтому пробовать начал сразу в рабочем проекте. В этой статье покажу как выглядит рабочий процесс с использованием openspec внутри opencode.</summary><content type="html">
  &lt;p id=&quot;vI0G&quot;&gt;Примерно два месяца назад я узнал про &lt;a href=&quot;https://github.com/Fission-AI/openspec&quot; target=&quot;_blank&quot;&gt;openspec&lt;/a&gt;, и решил попробовать. Пет-проекты на тот момент были на паузе, поэтому пробовать начал сразу в рабочем проекте. В этой статье покажу как выглядит рабочий процесс с использованием &lt;strong&gt;openspec&lt;/strong&gt; внутри &lt;strong&gt;opencode&lt;/strong&gt;.&lt;/p&gt;
  &lt;p id=&quot;7W5G&quot;&gt;Дублировать документацию из гитхаба не буду - ее можно прочитать по ссылке в первом абзаце, а расскажу именно про мой опыт использования &lt;em&gt;openspec&lt;/em&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;ybcG&quot;&gt;Установка в проекте&lt;/h2&gt;
  &lt;p id=&quot;4mQl&quot;&gt;В терминале в папке с проектом выполнил команду &lt;code&gt;openspec init&lt;/code&gt; и отметил нужные инструменты (&lt;em&gt;opencode&lt;/em&gt; и т.д.)&lt;/p&gt;
  &lt;figure id=&quot;rfYQ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f1/5d/f15d7427-e310-4ff3-9992-d20d928d0596.png&quot; width=&quot;1028&quot; /&gt;
    &lt;figcaption&gt;Выбрал opencode&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;mjs4&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/36/6c/366c67f5-8518-4fd7-ac25-2da29805269c.png&quot; width=&quot;1026&quot; /&gt;
    &lt;figcaption&gt;После нажатия enter нужно перезагрузить IDE, в моем случае - просто завершить сеанс opencode в терминале и запустить его заново&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;TJmR&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/12/2b/122b0da8-e227-4526-b7d5-b10dde024185.png&quot; width=&quot;996&quot; /&gt;
    &lt;figcaption&gt;Теперь нужно закоммитить добавленные в проект навыки и команды, чтобы ими можно было пользоваться&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;06kT&quot;&gt;Использование в работе&lt;/h2&gt;
  &lt;p id=&quot;cab8&quot;&gt;Запускаем &lt;em&gt;opencode&lt;/em&gt; и начинаем вводить команду &lt;code&gt;/o&lt;/code&gt;&lt;/p&gt;
  &lt;figure id=&quot;7Dkp&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/af/d9/afd95472-f7bc-4d89-a477-aa1adf90dcf0.png&quot; width=&quot;2042&quot; /&gt;
    &lt;figcaption&gt;Первые несколько секунд идет загрузка всех команд, а потом в списке появляются новые команды openspec&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;y2NE&quot;&gt;Новая мелкая фича&lt;/h3&gt;
  &lt;p id=&quot;xgTV&quot;&gt;Если есть &lt;strong&gt;полное понимание, что нужно делать&lt;/strong&gt;, то можно сразу использовать &lt;code&gt;/opsx-ff&lt;/code&gt; - я так делал два раза для мелких задач, где все максимально очевидно и обсуждать нечего, например:&lt;/p&gt;
  &lt;pre id=&quot;hkWL&quot;&gt;/opsx-ff task1234-toggle&lt;/pre&gt;
  &lt;p id=&quot;9tC6&quot;&gt;Тут &lt;strong&gt;task1234-toggle&lt;/strong&gt; является кратким названием задачи - это важное название и лучше делать его уникальным, чтобы потом было проще ориентироваться в задачах. Потом для продолжения работы над задачей может потребоваться явно передать в промпте это самое название задачи, чтобы агент знал, над которой задачей вы сейчас работаете.&lt;/p&gt;
  &lt;p id=&quot;Kw3Z&quot;&gt;Отправляем промпт в работу, и получаем ответ типа такого: &lt;/p&gt;
  &lt;blockquote id=&quot;3xDA&quot;&gt;I found existing toggle-related code in the project (reminder settings toggle, filter dialog toggle), but &amp;quot;task-1234-toggle&amp;quot; doesn&amp;#x27;t tell me what you want to build or fix.&lt;br /&gt;What do you want this change to do? For example:&lt;br /&gt;- Add a new toggle for some feature&lt;br /&gt;- Fix a bug with an existing toggle&lt;br /&gt;- Refactor toggle logic&lt;br /&gt;Describe the feature/fix and I&amp;#x27;ll create all the OpenSpec artifacts.&lt;/blockquote&gt;
  &lt;p id=&quot;0UWn&quot;&gt;Дальше отправляю промпт с кратким описанием фичи (ведь она мелкая):&lt;/p&gt;
  &lt;blockquote id=&quot;XKrp&quot;&gt;нужно сделать фичефлаг для настройки возможности включения или отключения экрана с логами для разработчика на экране&lt;/blockquote&gt;
  &lt;p id=&quot;EqEq&quot;&gt;Агент какое-то время думает и создает все необходимые документы (артефакты) по задаче:&lt;/p&gt;
  &lt;figure id=&quot;lrtu&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/28/e7/28e70851-53e2-4d00-bf16-689adb0b306a.png&quot; width=&quot;1474&quot; /&gt;
    &lt;figcaption&gt;Окончание работы по созданию документов к задаче&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;5Pa5&quot;&gt;Теперь нужно проверить получившиеся документы самостоятельно (т.к. там действительно немного текста) и при обнаружении нестыковок/ошибок нужно внести правки в документы (вручную или опять же через агента).&lt;/p&gt;
  &lt;p id=&quot;uMFm&quot;&gt;После проверки/исправления всех документов можно сразу переходить к &lt;code&gt;/opsx-apply&lt;/code&gt; или сохранить прогресс (делаем коммит) и переключиться на что-то еще.&lt;/p&gt;
  &lt;h3 id=&quot;crQZ&quot;&gt;Новая стандартная фича&lt;/h3&gt;
  &lt;p id=&quot;eMVp&quot;&gt;Если хочется больше контроля над процессом создания документации, или еще не до конца известны все требования для задачи, то есть смысл начинать с команды &lt;code&gt;/opsx-new&lt;/code&gt;, например:&lt;/p&gt;
  &lt;pre id=&quot;iJJ6&quot;&gt;/opsx-new task1234-medium-feature&lt;/pre&gt;
  &lt;p id=&quot;U2kO&quot;&gt;Отправляем этот промпт и получаем ответ: &lt;/p&gt;
  &lt;blockquote id=&quot;rZbF&quot;&gt;Here&amp;#x27;s the summary:&lt;br /&gt;Change: task1234-medium-feature&lt;br /&gt;Location: openspec/changes/task1234-medium-feature/&lt;br /&gt;Schema: spec-driven (4 artifacts)&lt;br /&gt;Progress: 0/4 complete&lt;br /&gt;[ ] proposal          ← ready now&lt;br /&gt;[-] design             (blocked by: proposal)&lt;br /&gt;[-] specs              (blocked by: proposal)&lt;br /&gt;[-] tasks               (blocked by: design, specs)&lt;br /&gt;First artifact: proposal.md — establish why this change is needed.&lt;br /&gt;Template:&lt;br /&gt;## Why&lt;br /&gt;&amp;lt;!-- Problem/opportunity, 1-2 sentences --&amp;gt;&lt;/blockquote&gt;
  &lt;blockquote id=&quot;Jk78&quot;&gt;## What Changes&lt;br /&gt;&amp;lt;!-- Bullet list: new capabilities, modifications, removals --&amp;gt;&lt;/blockquote&gt;
  &lt;blockquote id=&quot;jhkE&quot;&gt;## Capabilities&lt;br /&gt;### New Capabilities&lt;br /&gt;- &amp;#x60;&amp;lt;name&amp;gt;&amp;#x60;: &amp;lt;description&amp;gt;&lt;/blockquote&gt;
  &lt;blockquote id=&quot;IzeZ&quot;&gt;### Modified Capabilities&lt;br /&gt;&amp;lt;!-- List only if spec-level behavior changes --&amp;gt;&lt;/blockquote&gt;
  &lt;blockquote id=&quot;nLhC&quot;&gt;## Impact&lt;br /&gt;&amp;lt;!— Affected code, APIs, dependencies --&amp;gt;&lt;br /&gt;Ready to create the first artifact? Run /opsx-continue or describe what this change is about and I&amp;#x27;ll draft it.&lt;/blockquote&gt;
  &lt;p id=&quot;RYdh&quot;&gt;В таком сценарии можно делать все документы по порядку, начиная с &lt;em&gt;proposal&lt;/em&gt;, который является кратким описанием задачи для последующей детализации в других документах, напишем промпт с использованием команды &lt;code&gt;/opsx-continue&lt;/code&gt;:&lt;/p&gt;
  &lt;blockquote id=&quot;5Hrr&quot;&gt;/opsx-continue task1234-medium-feature нужно сделать фичефлаг для настройки возможности включения или отключения экрана с логами для разработчика на экране&lt;/blockquote&gt;
  &lt;p id=&quot;o1So&quot;&gt;Отправляем этот промпт и получаем ответ: &lt;/p&gt;
  &lt;blockquote id=&quot;rvTT&quot;&gt;Created: proposal.md&lt;br /&gt;Schema: spec-driven | Progress: 1/4&lt;br /&gt;[x] proposal       ✓&lt;br /&gt;[ ] design          ← unlocked&lt;br /&gt;[ ] specs           ← unlocked&lt;br /&gt;[-] tasks           (blocked by: design, specs)&lt;br /&gt;What&amp;#x27;s in the proposal:&lt;br /&gt;- Why: Нет способа просмотреть логи внутри приложения, нужна фиче-флаг для скрытия от обычных пользователей&lt;br /&gt;- Capabilities: dev-log-screen (экран логов) + dev-log-feature-flag (флаг управления)&lt;br /&gt;- Impact: AppSettingsDataStore, Screen, MoreScreen, новый DevLogScreen + ViewModel&lt;br /&gt;Ready to create the next artifact? Run /opsx-continue — I&amp;#x27;ll draft either design.md or the spec files next.&lt;/blockquote&gt;
  &lt;p id=&quot;5jqU&quot;&gt;Теперь читаем &lt;em&gt;proposal&lt;/em&gt;, вносим правки при необходимости, и либо продолжаем дальше работу в том же формате с командой &lt;code&gt;/opsx-continue&lt;/code&gt;, либо ставим на паузу и переключаемся на что-то другое - главное сделать коммит, чтобы сохранить прогресс.&lt;/p&gt;
  &lt;p id=&quot;BIad&quot;&gt;В нашем случае для примера я &amp;quot;промотаю&amp;quot; создание документов командой &lt;code&gt;/opsx-ff&lt;/code&gt;, чтобы показать как работает &lt;code&gt;/opsx-apply&lt;/code&gt;:&lt;/p&gt;
  &lt;figure id=&quot;F9tI&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/82/a9/82a96c7a-a47a-4f30-a635-574989f86196.png&quot; width=&quot;956&quot; /&gt;
    &lt;figcaption&gt;Агент начал работу&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;1yVU&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/73/64/7364e7c0-773d-41dd-8cb8-e62bfb4e49bd.png&quot; width=&quot;1658&quot; /&gt;
    &lt;figcaption&gt;После окончания работы агент предлагает добавить фичу в архив как выполненную&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;oEUp&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/26/2b/262b15ba-3959-4f58-ae83-28809846a83c.png&quot; width=&quot;1260&quot; /&gt;
    &lt;figcaption&gt;Результат работы - тоггл &amp;quot;Developer logs&amp;quot;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;LMey&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c4/dd/c4ddd3fe-cddd-41ef-bace-31c43027b5ca.png&quot; width=&quot;1260&quot; /&gt;
    &lt;figcaption&gt;Если тоггл включить, появится новая кнопка Dev Log&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;CviC&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/92/4a/924ac31c-de1a-4556-a221-ae31446b59c2.png&quot; width=&quot;1260&quot; /&gt;
    &lt;figcaption&gt;А вот и сам экран логов&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;mHIn&quot;&gt;Представим, что положение тоггла было таким и задумано изначально.&lt;/p&gt;
  &lt;p id=&quot;4Afv&quot;&gt;И вот пришло новое требование (ну ничего себе) - нужно тоггл переместить в нижнюю часть экрана. Правим артефакты либо вручную, либо новым промптом (без использования команд &lt;code&gt;/opsx&lt;/code&gt;) и снова вызываем &lt;code&gt;/opsx-apply&lt;/code&gt; для применения правок в коде:&lt;/p&gt;
  &lt;figure id=&quot;FXjg&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b7/37/b73750e2-8a67-4fb3-bad2-63c57fc55742.png&quot; width=&quot;1260&quot; /&gt;
    &lt;figcaption&gt;Успех! Положение тоггла исправлено&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;ZL9p&quot;&gt;Верификация статуса&lt;/h3&gt;
  &lt;p id=&quot;RnoL&quot;&gt;Бывает, что задача откладывается на неопределенный срок, пока ее тестируют, обсуждают и т.д., и все это время код по задаче не пишется, но возможно меняются документы (вручную или нет, не важно).&lt;/p&gt;
  &lt;p id=&quot;ZqfY&quot;&gt;Когда к задаче нужно вернуться, то можно проверить статус с помощью команды &lt;code&gt;/opsx-verify&lt;/code&gt;, это я и сделал в нашем случае, вот итоги проверки:&lt;/p&gt;
  &lt;blockquote id=&quot;AM6H&quot;&gt;No critical issues found. &lt;br /&gt;3 warnings to consider — all minor. The implementation correctly follows all design decisions, covers all requirements and scenarios, and maintains code pattern consistency.&lt;br /&gt;Ready for archive. ✓&lt;/blockquote&gt;
  &lt;p id=&quot;d5Hl&quot;&gt;Там сначала идет отчет по шаблону, и в нем перечислены все детали проверок, в нашем случае их нет смысла смотреть, но в реальной задаче следует прочитать и убедиться, что все корректно.&lt;/p&gt;
  &lt;p id=&quot;4sHl&quot;&gt;Когда задачу &amp;quot;приняли&amp;quot; окончательно, ее нужно архивировать командой &lt;code&gt;/opsx-archive&lt;/code&gt;:&lt;/p&gt;
  &lt;blockquote id=&quot;XZmm&quot;&gt;Archive Complete&lt;br /&gt;Change: task1234-medium-feature&lt;br /&gt;Schema: spec-driven&lt;br /&gt;Archived to: openspec/changes/archive/2026-06-27-task1234-medium-feature/&lt;br /&gt;Specs: Delta specs preserved (new capabilities — no main specs to sync to)&lt;br /&gt;All 4 artifacts complete. All 20 tasks complete.&lt;/blockquote&gt;
  &lt;p id=&quot;10QY&quot;&gt;Вот и все! Работа над задачей завершена, теперь любые доработки нужно делать через отдельные задачи (&lt;code&gt;/opsx-new&lt;/code&gt; или &lt;code&gt;/opsx-ff&lt;/code&gt;).&lt;/p&gt;
  &lt;h2 id=&quot;oMdM&quot;&gt;Мой отзыв&lt;/h2&gt;
  &lt;p id=&quot;j5oY&quot;&gt;Мне нравится использовать &lt;em&gt;openspec&lt;/em&gt;, потому что:&lt;/p&gt;
  &lt;ol id=&quot;td2B&quot;&gt;
    &lt;li id=&quot;q6RM&quot;&gt;Стандартизируется рабочий процесс - сначала документация, потом реализация по четкому плану&lt;/li&gt;
    &lt;li id=&quot;2kwI&quot;&gt;Появляется документация в удобном формате прямо в папке с проектом, а не где-то далеко в отдельной системе&lt;/li&gt;
    &lt;li id=&quot;Dzqq&quot;&gt;Удобно отслеживать работу и возвращаться к задаче после длительного перерыва&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;g4Iy&quot;&gt;Не нравится, что агент часто генерирует документацию на английском. Да что уж там, иногда иероглифы до сих пор вставляет то тут, то там 😅, но даже с учетом этого недостатка штука очень удобная.&lt;/p&gt;
  &lt;h3 id=&quot;gfRB&quot;&gt;Нюансы&lt;/h3&gt;
  &lt;ul id=&quot;Rj3x&quot;&gt;
    &lt;li id=&quot;C9Ld&quot;&gt;Многое зависит от используемой модели и настроек проекта (в том числе &lt;code&gt;AGENTS.md&lt;/code&gt;) - не нужно ожидать классную реализацию плана с нужным стилем/подходом, если агент не знает ничего этого&lt;/li&gt;
    &lt;li id=&quot;TsXh&quot;&gt;Даже если проект настроен правильно, нейросеть может ошибиться в составлении документации (например), и потом сделать работу по неправильному плану, поэтому нужно перепроверять документацию и реализацию (как это делать - другой вопрос, кто-то будет сам читать, а у кого-то будут автоматизированные проверки)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;F6RT&quot;&gt;Еще раз ссылка на репозиторий &lt;a href=&quot;https://github.com/Fission-AI/openspec&quot; target=&quot;_blank&quot;&gt;openspec&lt;/a&gt;, рекомендую попробовать самостоятельно 😉&lt;/p&gt;

</content></entry><entry><id>easy_dev991:Greg5st017e</id><link rel="alternate" type="text/html" href="https://teletype.in/@easy_dev991/Greg5st017e?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=easy_dev991"></link><title>Краткий обзор RTK</title><published>2026-06-08T16:46:02.849Z</published><updated>2026-06-08T16:48:49.996Z</updated><summary type="html">Недавно нашёл ещё один полезный инструмент для использования в opencode — RTK (Rust Token Killer).</summary><content type="html">
  &lt;p id=&quot;w7ME&quot;&gt;Недавно нашёл ещё один полезный инструмент для использования в &lt;code&gt;opencode&lt;/code&gt; — &lt;a href=&quot;https://github.com/rtk-ai/rtk&quot; target=&quot;_blank&quot;&gt;RTK&lt;/a&gt; (Rust Token Killer). &lt;/p&gt;
  &lt;p id=&quot;0Fj6&quot;&gt;Устанавливается одной командой, встраивается через &lt;code&gt;hook&lt;/code&gt; и автоматом сжимает вывод команд перед тем, как он попадёт в контекст нейросети.&lt;/p&gt;
  &lt;h2 id=&quot;md-heading-1&quot;&gt;Как это работает&lt;/h2&gt;
  &lt;p id=&quot;WxZl&quot;&gt;RTK перехватывает команды и применяет к ним четыре стратегии:&lt;/p&gt;
  &lt;ol id=&quot;s7Ip&quot;&gt;
    &lt;li id=&quot;vnBU&quot;&gt;фильтрацию шума&lt;/li&gt;
    &lt;li id=&quot;yzP2&quot;&gt;группировку похожих элементов&lt;/li&gt;
    &lt;li id=&quot;vIF7&quot;&gt;обрезку лишнего&lt;/li&gt;
    &lt;li id=&quot;OidT&quot;&gt;дедупликацию повторяющихся строк.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;GNyd&quot;&gt;В результате модель получает ровно ту же информацию, но в 3–10 раз меньше токенов.&lt;/p&gt;
  &lt;h2 id=&quot;n0jx&quot;&gt;Примеры&lt;/h2&gt;
  &lt;h3 id=&quot;NRgE&quot;&gt;git status&lt;/h3&gt;
  &lt;p id=&quot;QtR5&quot;&gt;&lt;strong&gt;Без RTK (~67 токенов):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;RKpk&quot;&gt;On branch main
Your branch is up to date with &amp;#x27;origin/main&amp;#x27;.&lt;/pre&gt;
  &lt;pre id=&quot;F0jd&quot;&gt;Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)
	.serena/
	docs/&lt;/pre&gt;
  &lt;pre id=&quot;nzIL&quot;&gt;nothing added to commit but untracked files present&lt;/pre&gt;
  &lt;p id=&quot;jgZs&quot;&gt;&lt;strong&gt;С RTK (~12 токенов):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;q1dT&quot;&gt;* main...origin/main
?? .serena/
?? docs/&lt;/pre&gt;
  &lt;p id=&quot;qrOY&quot;&gt;Шесть строк превратились в три — при этом полезная информация не потерялась.&lt;/p&gt;
  &lt;h3 id=&quot;md-heading-3&quot;&gt;git diff&lt;/h3&gt;
  &lt;p id=&quot;ZSau&quot;&gt;&lt;strong&gt;Без RTK (~200 токенов):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;1jgr&quot;&gt;diff --git a/Shared SwiftUI Content/100_ScenePhaseExample.swift b/Shared SwiftUI Content/100_ScenePhaseExample.swift
index 3a4b5c6d..7e8f9a0b 100644
--- a/Shared SwiftUI Content/100_ScenePhaseExample.swift
+++ b/Shared SwiftUI Content/100_ScenePhaseExample.swift
@@ -10,6 +10,7 @@ struct ScenePhaseExample: View {
     @State private var isActive = false&lt;/pre&gt;
  &lt;pre id=&quot;Mvwc&quot;&gt;     var body: some View {
+        // MARK: - Main Content
         VStack(spacing: 20) {
             Text(isActive ? &amp;quot;Active&amp;quot; : &amp;quot;Inactive&amp;quot;)
                 .font(.largeTitle)
&lt;/pre&gt;
  &lt;p id=&quot;tc4y&quot;&gt;&lt;strong&gt;С RTK (~40 токенов):&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;Ycrx&quot;&gt;100_ScenePhaseExample.swift: +1
  + // MARK: - Main Content&lt;/pre&gt;
  &lt;p id=&quot;ojbe&quot;&gt;RTK показывает только имя файла, количество изменённых строк и сами добавленные/удалённые строки — без служебной информации &lt;code&gt;diff&lt;/code&gt; (индексы, заголовки патчей, контекстные строки).&lt;/p&gt;
  &lt;h2 id=&quot;md-heading-4&quot;&gt;Установка и настройка&lt;/h2&gt;
  &lt;p id=&quot;5H4A&quot;&gt;С помощью &lt;code&gt;homebrew&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;lXBE&quot;&gt;brew install rtk&lt;/pre&gt;
  &lt;p id=&quot;E2E9&quot;&gt;После установки нужно инициализировать &lt;code&gt;hook&lt;/code&gt; для вашего рабочего инструмента:&lt;/p&gt;
  &lt;pre id=&quot;5JrW&quot;&gt;rtk init -g                     # Claude Code / Copilot (по умолчанию)
rtk init -g --gemini            # Gemini CLI
rtk init -g --codex             # Codex (OpenAI)
rtk init -g --agent cursor      # Cursor
rtk init -g --agent windsurf    # Windsurf
rtk init -g --opencode          # opencode&lt;/pre&gt;
  &lt;p id=&quot;gMNc&quot;&gt;После настройки для &lt;code&gt;opencode&lt;/code&gt; в &lt;code&gt;~/.config/opencode/plugins/&lt;/code&gt; появится файл &lt;code&gt;rtk.ts&lt;/code&gt;, который автоматически будет перехватывать вызовы Bash-инструмента и переписывать команды через RTK.&lt;/p&gt;
  &lt;h2 id=&quot;6309&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;mO1P&quot;&gt;RTK — это один из тех инструментов, которые ставишь один раз и сразу получаешь профит. Буквально за пару минут получаем экономию токенов, которая особенно заметна на длинных сессиях при работе с агентом 👍&lt;/p&gt;

</content></entry><entry><id>easy_dev991:orJ5fF-h3jo</id><link rel="alternate" type="text/html" href="https://teletype.in/@easy_dev991/orJ5fF-h3jo?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=easy_dev991"></link><title>Подключаем нейросеть к Xcode</title><published>2026-06-05T09:13:54.508Z</published><updated>2026-06-05T09:16:02.560Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/41/b0/41b08270-305a-4266-9621-30807738876d.png"></media:thumbnail><category term="i-os" label="iOS"></category><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/00/39/003964b1-9383-45db-95d7-d066878e3662.png&quot;&gt;В прошлом году презентовали Xcode 26 с возможностью добавления других провайдеров нейросетей кроме chatgpt/claude, но вот незадача - это не так и просто сделать, если не погуглить дополнительно.</summary><content type="html">
  &lt;figure id=&quot;litW&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/00/39/003964b1-9383-45db-95d7-d066878e3662.png&quot; width=&quot;1644&quot; /&gt;
    &lt;figcaption&gt;Xcode выдает ошибку при попытке подключить kimi&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;8cJO&quot;&gt;В прошлом году презентовали &lt;code&gt;Xcode 26&lt;/code&gt; с возможностью добавления других провайдеров нейросетей кроме &lt;code&gt;chatgpt&lt;/code&gt;/&lt;code&gt;claude&lt;/code&gt;, но вот незадача - это не так и просто сделать, если не погуглить дополнительно.&lt;/p&gt;
  &lt;p id=&quot;zeAm&quot;&gt;Для сравнения вот как выглядит настройка в &lt;code&gt;Android Studio&lt;/code&gt;:&lt;/p&gt;
  &lt;figure id=&quot;xXMO&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/55/92/55928ade-57ee-4450-9b14-900c6ccb68cd.png&quot; width=&quot;2188&quot; /&gt;
    &lt;figcaption&gt;Подключается с первого раза без ошибок, чудеса&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;9JLP&quot;&gt;Если просто ввести в настройках &lt;code&gt;Xcode&lt;/code&gt; те же данные, что в &lt;code&gt;Android Studio&lt;/code&gt;, то ничего не выйдет.&lt;/p&gt;
  &lt;p id=&quot;8Tpz&quot;&gt;Причина проблемы в поле URL: &lt;code&gt;Xcode&lt;/code&gt; автоматически добавляет &lt;code&gt;/v1/models&lt;/code&gt; или &lt;code&gt;/models&lt;/code&gt; к URL провайдера для валидации подключения.&lt;/p&gt;
  &lt;p id=&quot;A0QU&quot;&gt;Поэтому нужно удалить часть URL с версией... чтобы &lt;code&gt;Xcode&lt;/code&gt; сам подставил ее. &lt;/p&gt;
  &lt;p id=&quot;t0Tx&quot;&gt;Гениально, не так ли?&lt;/p&gt;
  &lt;figure id=&quot;3xPJ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/56/14/56140c5d-9238-46f0-8dac-38a9c5c0f47c.png&quot; width=&quot;1644&quot; /&gt;
    &lt;figcaption&gt;Пример корректной настройки для kimi в Xcode&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;h6Ms&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c2/6d/c26de0e7-40a0-470f-be71-6a91757bd641.png&quot; width=&quot;1644&quot; /&gt;
    &lt;figcaption&gt;Успешно подключили kimi&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;LJKL&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d0/eb/d0ebadfc-fd5c-44f4-8601-b76bc07ecd4e.png&quot; width=&quot;1644&quot; /&gt;
    &lt;figcaption&gt;Детальный экран подключенного kimi&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;T3Zs&quot;&gt;И чтобы не было подозрений, что я рекламирую kimi для &lt;code&gt;Xcode&lt;/code&gt;:&lt;/p&gt;
  &lt;figure id=&quot;NdSr&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/ba/2b/ba2b11f6-2724-415a-8023-7c81b2bde693.png&quot; width=&quot;780&quot; /&gt;
    &lt;figcaption&gt;kimi нифига не работает в Xcode&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;4JiK&quot;&gt;Всем удачных подключений!&lt;/p&gt;

</content></entry><entry><id>easy_dev991:P3qUJL1LTfs</id><link rel="alternate" type="text/html" href="https://teletype.in/@easy_dev991/P3qUJL1LTfs?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=easy_dev991"></link><title>Отказ от Icon Composer</title><published>2026-04-19T14:01:16.566Z</published><updated>2026-04-19T14:02:20.280Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/58/bc/58bc94a6-a0ca-4458-a234-7251c37302f2.png"></media:thumbnail><category term="i-os" label="iOS"></category><summary type="html">Если у вас в приложение несколько альтернативных иконок, и все они сделаны с использованием Icon Composer, эта статья для вас.</summary><content type="html">
  &lt;p id=&quot;YYRP&quot;&gt;Если у вас в приложение несколько альтернативных иконок, и все они сделаны с использованием &lt;code&gt;Icon Composer&lt;/code&gt;, эта статья для вас.&lt;/p&gt;
  &lt;p id=&quot;vTFC&quot;&gt;Или если у вас простая иконка, которая почему-то получает тень или стекло при установке приложения на девайс, эта статья для вас.&lt;/p&gt;
  &lt;h2 id=&quot;HgRL&quot;&gt;Предыстория&lt;/h2&gt;
  &lt;p id=&quot;g4ku&quot;&gt;В &lt;code&gt;Xcode 26.1&lt;/code&gt; добавили баг при создании сборки приложения - ассеты иконок, сделанных в &lt;code&gt;Icon Composer&lt;/code&gt; добавляются в итоговый архив несколько раз, что приводит к заметному увеличению веса приложения. Ссылки на форум: &lt;a href=&quot;https://developer.apple.com/forums/thread/804739&quot; target=&quot;_blank&quot;&gt;первая&lt;/a&gt;, &lt;a href=&quot;https://developer.apple.com/forums/thread/821826&quot; target=&quot;_blank&quot;&gt;вторая&lt;/a&gt;.&lt;/p&gt;
  &lt;p id=&quot;PvjP&quot;&gt;Если иконку создать в композере, то она будет выглядеть как и задумано, вот только в итоговой сборке эта иконка будет весить в несколько раз больше, чем нужно. И если в приложении есть альтернативные иконки, то общий вес легко может вырасти в 2 раза для легкого приложения (например, &lt;a href=&quot;https://github.com/easydev991/SwiftUI-Days&quot; target=&quot;_blank&quot;&gt;этого&lt;/a&gt;).&lt;/p&gt;
  &lt;p id=&quot;nJmG&quot;&gt;Обходное решение есть - не использовать композер, и добавлять иконки в приложение старым способом (через ассеты).&lt;/p&gt;
  &lt;p id=&quot;Ctmr&quot;&gt;Однако для простых иконок это приводит к некрасивому результату:&lt;/p&gt;
  &lt;figure id=&quot;OF4i&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b8/ee/b8ee6a3f-71f4-42ab-a3a8-39d359cc5c86.jpeg&quot; width=&quot;136&quot; /&gt;
    &lt;figcaption&gt;Иконка приложения с дефолтным градиентом&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;blockquote id=&quot;8LLt&quot;&gt;Простой я называю иконку, которая состоит из двух цветов без градиентов или прозрачности.&lt;/blockquote&gt;
  &lt;p id=&quot;EoRK&quot;&gt;Получается, что либо мы снижаем вес приложения и миримся с некрасивой тенью (или стеклом, в зависимости от иконки), либо соглашаемся с повышением веса приложения, и целиком управляем тенями и стеклом (привет, композер)?&lt;/p&gt;
  &lt;p id=&quot;HFqF&quot;&gt;&lt;u&gt;Так не пойдет.&lt;/u&gt;&lt;/p&gt;
  &lt;h2 id=&quot;xSmz&quot;&gt;Решение&lt;/h2&gt;
  &lt;figure id=&quot;vRDD&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/ff/fe/fffe123e-29d3-46c1-baaa-56474e25c881.png&quot; width=&quot;472&quot; /&gt;
    &lt;figcaption&gt;Настройка градиента в фигме - добавляем градиент для иконки, чтобы система не считала картинку такой уж простой для накладывания своих лишних эффектов&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;E9Du&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c0/cd/c0cd6390-2008-4cf8-bd99-0541f6e61f57.png&quot; width=&quot;1850&quot; /&gt;
    &lt;figcaption&gt;Слева старая иконка без градиентов, справа - новая с градиентом. Глазом разницу почти не видно, зато избавляемся от некрасивой тени на экране девайса&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;1PqV&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/00/7b/007b9eb9-19a1-424a-86bb-be3b37aa06ec.png&quot; width=&quot;154&quot; /&gt;
    &lt;figcaption&gt;Так выглядит новая иконка с незаметным градиентом на экране девайса - без тени и стекла&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;AGCC&quot;&gt;Результат в мегабайтах&lt;/h2&gt;
  &lt;figure id=&quot;PFrQ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/3b/55/3b55d6bf-f705-4c92-967b-7611f85b0508.png&quot; width=&quot;1408&quot; /&gt;
    &lt;figcaption&gt;Размер приложения с иконками, сделанными в Icon Composer&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;TVbJ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f9/72/f972833b-1bed-46c8-8b46-2d40580ca6f2.png&quot; width=&quot;1410&quot; /&gt;
    &lt;figcaption&gt;Размер приложения после обновления основной иконки и альтернативных&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;DLAY&quot;&gt;Вес приложения снизился почти на 4 мегабайта!&lt;/p&gt;
  &lt;p id=&quot;FF7Z&quot;&gt;И при этом новые градиентные иконки весят в 5-7 раз больше, чем простые однотонные. Но простые, как мы уже знаем, система покрывает своим стеклом или тенью, а выглядит это некрасиво.&lt;/p&gt;
  &lt;p id=&quot;nbJQ&quot;&gt;Интересный момент: в темной теме ни стекло, ни дополнительная тень на иконки не накладывается - по крайней мере в &lt;a href=&quot;https://github.com/easydev991/SwiftUI-Days&quot; target=&quot;_blank&quot;&gt;счётчике дней&lt;/a&gt; так.&lt;/p&gt;
  &lt;h2 id=&quot;JHCS&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;ZbjO&quot;&gt;Если у вас в приложении много альтернативных иконок, или вы используете &lt;code&gt;Icon Composer&lt;/code&gt; для создания ваших иконок, то будет здорово вернуться к ассетам и подождать, пока композер починят (а починить его не могут уже больше 5 месяцев).&lt;/p&gt;
  &lt;p id=&quot;QSpa&quot;&gt;Зачем заставлять пользователя скачивать лишние мегабайты мусора вместе с нормальным приложением?&lt;/p&gt;

</content></entry><entry><id>easy_dev991:h91zeBj4yyW</id><link rel="alternate" type="text/html" href="https://teletype.in/@easy_dev991/h91zeBj4yyW?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=easy_dev991"></link><title>Чиним синхронизацию Swift Data</title><published>2026-04-17T19:28:53.706Z</published><updated>2026-04-17T19:29:09.532Z</updated><category term="i-os" label="iOS"></category><summary type="html">В моем iOS-приложении для подсчета дней используется Swift Data и в проекте все настроено для автоматической синхронизации данных между всеми девайсами пользователя в iCloud. Сегодня я починил эту синхронизацию (она давно не работала).</summary><content type="html">
  &lt;p id=&quot;4xrH&quot;&gt;В моем &lt;a href=&quot;https://github.com/easydev991/SwiftUI-Days&quot; target=&quot;_blank&quot;&gt;iOS-приложении для подсчета дней&lt;/a&gt; используется &lt;code&gt;Swift Data&lt;/code&gt; и в проекте все настроено для автоматической синхронизации данных между всеми девайсами пользователя в &lt;code&gt;iCloud&lt;/code&gt;. Сегодня я починил эту синхронизацию (она давно не работала).&lt;/p&gt;
  &lt;h2 id=&quot;1IlA&quot;&gt;Проблемный сценарий&lt;/h2&gt;
  &lt;p id=&quot;TAct&quot;&gt;На одном девайсе создаю запись в приложении, жду, сворачиваю/разворачиваю приложение, проверяю на другом девайсе через минуту - там эта запись не появляется.&lt;/p&gt;
  &lt;h2 id=&quot;cC8P&quot;&gt;Решение&lt;/h2&gt;
  &lt;p id=&quot;M3Vp&quot;&gt;Открываем &lt;a href=&quot;https://icloud.developer.apple.com/&quot; target=&quot;_blank&quot;&gt;https://icloud.developer.apple.com/&lt;/a&gt;&lt;/p&gt;
  &lt;figure id=&quot;rBMx&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/19/e7/19e78701-e72f-48f0-9809-a07c98bf2ece.png&quot; width=&quot;1864&quot; /&gt;
    &lt;figcaption&gt;Жмем CloudKit Database&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;oUtH&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ae/3a/ae3af325-ccc8-4790-bbd5-aab8c031ea7f.png&quot; width=&quot;848&quot; /&gt;
    &lt;figcaption&gt;Выбираем справа сверху настроенный для приложения контейнер и вариант Production&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;3Vy9&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/af/61/af617173-007e-4dbd-83f7-a7c911f67040.png&quot; width=&quot;908&quot; /&gt;
    &lt;figcaption&gt;Открываем логи&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;MLqd&quot;&gt;Находим запись с ошибкой, например так:&lt;/p&gt;
  &lt;figure id=&quot;U2v2&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d8/f9/d8f993b1-a68d-485d-b47d-df89835d91dd.png&quot; width=&quot;3168&quot; /&gt;
    &lt;figcaption&gt;Фильтруем по OverallStatus = USER_ERROR и жмем справа синюю кнопку Query&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;DEY9&quot;&gt;Проверяем схему (типы записей) в development и production&lt;/p&gt;
  &lt;figure id=&quot;cPuV&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/93/5c/935cd717-10d2-4571-ba26-5ccf72210d31.png&quot; width=&quot;446&quot; /&gt;
    &lt;figcaption&gt;Жмем сюда для development и production по очереди, чтобы убедиться в наличии нестыковок&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;x0Vg&quot;&gt;Нестыковки найти очень легко: в моем случае в production-схеме буквально не было нужного типа записи с полями из iOS-приложения.&lt;/p&gt;
  &lt;figure id=&quot;OlPK&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/e5/78/e57896b4-472b-42a4-bd7f-c6b958543fa2.png&quot; width=&quot;3210&quot; /&gt;
    &lt;figcaption&gt;Вот как у меня было в прод-схеме - только один тип записи &amp;quot;Users&amp;quot;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Q3Nl&quot;&gt;Если найдены нестыковки, и development-схема содержит более актуальные данные, нужно ... опубликовать эти изменения в прод.&lt;/p&gt;
  &lt;figure id=&quot;Incq&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/06/ce/06cee1f4-1fc5-4c55-8ce9-18c079d8aa12.png&quot; width=&quot;3202&quot; /&gt;
    &lt;figcaption&gt;Вот как у меня было в дев-схеме (есть нужный мне тип записи &amp;quot;CD_Item&amp;quot;), и тут же выделил слева внизу кнопку для публикации изменений&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;C4MW&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/33/4a/334ae115-28fd-4fc0-8f26-d6ef91b1f1a8.png&quot; width=&quot;1292&quot; /&gt;
    &lt;figcaption&gt;Перед деплоем можно посмотреть изменения - тут в общем все поля моей модели данных, которая используется в &amp;quot;Счётчике дней&amp;quot; на iOS&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Qit4&quot;&gt;После нажатия &amp;quot;Deploy&amp;quot; можно подождать пару минут и повторить тест на проблемном сценарии. У меня проблема была решена через 2 минуты после деплоя актуальной схемы в прод.&lt;/p&gt;
  &lt;h2 id=&quot;6EhW&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;l4tE&quot;&gt;Когда я в первый раз настраивал &lt;code&gt;Swift Data&lt;/code&gt;, то вообще не заглядывал в консоль &lt;code&gt;icloud.developer&lt;/code&gt;, не проверял ничего связанного со схемами, и даже статей на эту тему не искал и не читал. Оказалось, настроить синхронизацию с облаком несложно, нужно только знать как это делается 😅&lt;/p&gt;
  &lt;p id=&quot;bws5&quot;&gt;Спасибо интернету! И нейросетям 😉&lt;/p&gt;

</content></entry></feed>