Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni

🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!

Пости з тегом #Адвент2024

21.12.2024

Дев-адвент 21: що робити з часом?

Нарешті наважився запустити застосунок на телефоні — там, де справжні дані. (Для того потрібна була стабільна схема бази, щоб не страждати потім з міграціями.) Що можу сказати — чудові покращення! Залишилось додати трохи сполучної тканини, та можна випускати.

Але поки задумався: як же ж дійсно залучити зібрані дані, щоб краще витрачати свої 24 години, 365 днів? Бо я саме заради цього все роблю. Ось кілька думок.

PS. Знаєте Steam Replay - звіт про те, в що грав цього року? В мене він не дуже обʼєктивний — по-перше, обліковку ділю з сином, тому в топі ігор Celeste та Super Meat Boy. По-друге, не всі мої ігри були в Steam… Зате всі є в тезі 🎮 gaming! Хочу зробити аналогічний звіт, але з даних трекера.


22.12.2024

Дев-адвент 22: дрібні, але важливі виправлення

Хоч мій трекер збудований на швидкому введенні тегів в несподіваний момент — мушу зізнатися, що вже довгий час (може, з пів року чи більше) сповіщення не відпрацьовували. Тобто, вони зʼявлялися, але перехід в застосунок відбувався без відкриття форми додавання проби. Ба більше, довгий час відкриття застосунку зі сповіщення взагалі викидувало через критичну помилку. 😳

З помилкою я вже цього місяця розібрався. Це була одна з тих бісячих ситуацій у Swift, коли застосунок отримує EXC_BREAKPOINT в асемблерному коді (тобто системному, без вихідного тексту) - та піди зʼясуй, в чому справа. Виявилося, що версія метода делегату didReceive з async не працює з моделлю рівночасності. (Класична проблема з офіційними API, на жаль.) Тому, контрінтуїтивно, повернувся до старої версії — з колбеком — та це мене врятувало. (На жаль, щоб це дізнатися, довелося, як в пазлі, пробувати всі комбінації по черзі.)

Але форма все ще не відкривалася. Причому код, що її відкриває зі сповіщення, був той самий, що й зі списку — тобто проблема була десь посередині. Думав, що в бізнес-логіці — ну, може, я погано шукаю пробу, яку треба відкрити. Може, не встигаю створити (бо створюються тільки проби за минуле, тому по відкриттю на сповіщення про зараз проба створюється “just-in-time”.)

Та виявилося, ні. Це була ще одне непорозуміння життєвого циклу, цього разу — всього застосунку. Бо застосунок у SwiftUI - це нащадок структури App. А в ній, як і в компонентах, в конструкторі стан @State ще не має привʼязки. Та якщо в конструкторі створити делегат сповіщень та передати йому той стан, що є — то він не зможе редагувати справжній стан.

Розвʼязалося все просто (коли вже знаєш, як воно працює!) Переніс створення делегату до обробника onAppear - тобто з конструктора в body. І все! Форма відкривається вчасно.


23.12.2024

Дев-адвент 23: графік розкладу тегу

🌶️ Ще один з гостро потрібних графіків — це схема тижневого розкладу тегу. Ідея в тому, що за ним можна зрозуміти, де справжній розклад не збігається з бажаним, та скоригувати.

🔘 В мене вже був такий графік, але я малював на ньому кожну пробу окремою крапочкою. За “хмарою” крапок можна було побачити ціле, але коли їх стає забагато, то вже нічого не зрозуміло — тому хотів замінити цей графік на теплову карту.

З першого погляду, це легко — підрахував проби за днями та годинами та й показуй — це як пряма заміна крапок на їхню кількість. Втім, як видно зверху справа, абсолютна кількість нам мало корисна. Краще відносна кількість, тобто як часто використовують цей тег в дану годину, порівняно з іншими тегами

Можемо витягнути відносну кількість з SQL одним запитом: COUNT(NULLIF(tagId != 123, TRUE))/CAST(COUNT(*) AS FLOAT). Взагалі останнім часом починаю роботу в клієнті SQLite, а потім вже переношу запити в застосунок — в SQL швидше виходить ітерувати.

🌚 Графік посередині — вже значно ясніше, з нього відразу зрозуміло, що вночі я сплю. Зліва — те ж саме, але я прибрав мітки з частотою до 5%. На мою думку, так менше шуму, але: з іншими тегами такої ж чіткості не буває, все через вільний графік.

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


24.12.2024

Дев-адвент 24: форма додавання проби

Освіжив форму додавання проби — ліворуч те як вона виглядала вже багато місяців, праворуч перша ітерація покращень.

(Взагалі, за досвідом, ця форма з усіма тегами ледве влазить в екран телефону. Особливо якщо відкрити клавіатуру — тому в мене зараз пошук тегів відкривається окремим модалом. Наступним кроком хочу його прибрати.)

PS. Найважче в реалізації дизайнів на SwiftUI - це знати інструментарій. Мабуть, так само як і з CSS. Бо коли не знаєш, наприклад, що можна отримати системний колір третинного фону як .background.tertiary, або як все ж працює викладка елементів (зовсім не як в CSS!), то виходитиме складно та незграбно.


25.12.2024

Дев-адвент 25: пошук тегів з форми

Сьогодні переробив пошук з форми. Багато чого не ідеально, але каркас готовий, та вже є зручнішим за попередню реалізацію.

Головна проблема цієї форми — їй дуже тісно. На телефоні мало місця. Особливо коли відкриєш клавіатуру — чого на відео не видно, бо то на емуляторі. Тому в мене пошук був окремим екраном, де йому вже була воля.

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

На те спробував поки що заміняти блок “ймовірних тегів” результатами пошуку. (А ще — ховати — з анімацією! - попередній та наступний теги, бо вони тут зайві.) Та обмежити результати за кількістю. Та показувати теги “потоком”, а не по одному на рядок. Наче непогано — хоча сам UX пошукового рядка ще треба доробити — щоб було легко очистити.

Наступне, що тут треба переробити — це логіку обирання отих “ймовірних тегів”; хочу агрегувати дані про суміжність тегів, щоб знайти “ідеальне поєднання” між наступними, попередніми, та спільними тегами до тих тегів, що вже відомі.


26.12.2024

Дев-адвент 26: цілісність дизайну та покращення пошуку

Нарешті взявся за остаточне впорядкування дизайну (ну, наскільки ці слова можна застосувати до цього MVP.) Якщо тег — це сірий округлий прямокутник, то таким він повинен бути всюди: тоді ясно, що це тег. Так само проби — більші округлі прямокутники з кольоровою крапкою: пропущено / заповнено / заповнено, але пізніше. Сюди можна витратити необмежену кількість часу, тому поки мета почати.

🎨 Відчуваю, що треба було б зробити палітру стилів, а не робити зміни там-сям, проте цим займуся пізніше. (У SwiftUI “палітра стилів” може існувати у вигляді набору модифікаторів.)

🏔️ Плюс чим далі, тим більше покращення UX тягнуть за собою додаткові покращення. Наприклад: є в мене автотегінг з Apple Health. Раніше було важко побачити його роботу в реальному часі, і це було… нормально. А тепер на головній є блок “незаповнені проби”, в якому видно, як стрибають спочатку порожні, а потім автозаповнені сном проби. Щоб було зрозуміло, тепер доведеться додати блок “автотегінг” з його результатами. І це гарно! Тільки роботи більшає.

🫥 На відео зверху видно новий UX додавання тегу. Просто до кінця списку результатів додаю пунктиром тег, який можна створити та відразу й додати. Також результати пошуку тепер спочатку показують теги зі збігом на початку (бо зазвичай саме так ми їх вводимо), а потім вже решту збігів.

🎅 Якщо все буде добре, планую до 1 січня все ж випуститися хоча б в TestFlight.


27.12.2024

Дев-адвент 27: рушії рекомендацій

…Продовжую роботу над формою. (Взагалі форма вводу — це UI #1 мого застосунку, тому є сенс її робити найкращою.) Пошук — це гарно, але ще краще — це мати потрібні теги обраними заздалегідь. Тут, фактично, йдеться про рушій рекомендацій — функцію з доступної інформації в пропоновані теги. Кілька думок

PS: пару днів назад я не міг зрозуміти, чи варто очищати пошук після вибору тегу. Наче це побічний ефект, незрозумілий для користувача. Але протестував на собі та зрозумів, що точно треба очищати — бо теги вводяться серією: laptop coding tracker - та старий зміст пошуку тільки заважає.

Так що намальовується такий UX: починаємо пропозиції з попереднього / наступного запису (можна навіть 2-3 попередніх). Після того, як обрані теги, рекомендуємо суміжні. Отак буде зручно, та не потребуватиме складного рушія. Бо я вже почав вигадувати “програмістське рішення”, де буде складний багатофакторний алгоритм.


29.12.2024

Дев-адвент 29: онбордінг та поради

🏁 Десь нещодавно чув — можливо, в документалці до 20-річчя Half-Life 2 (яку я всім раджу подивитись задля цікавих продуктових історій) - що перший рівень гри варто робити останнім, коли всі механіки та підходи вже пропрацьовані. Бо перше враження — головне, тож варто зробити його найсильнішим.

⏪ Із застосунками це теж доцільно. Протилежний підхід — почати розробку з онбордінгу — виглядає логічніше з першого погляду. Але тоді є ризик, що продукт розвиватиметься, а про онбордінг забудуть, та він застаріє. В моїй практиці таке вже бувало. Втім, якщо продукт великий та бюджет необмежений, то колись онбордінг перероблять наново. А от коли таких ресурсів немає, то краще все ж відкласти розробку першого знайомства на останнє.

🧪 Коли я тільки починав робити трекер, то вигадав для онбордінгу “тестову пробу”, в якій можна погратися з інтерфейсом та не дочікуватись першої справжньої проби. Нагадаю, що вони відбуваються за чітким графіком, причому є “стандартний” графік зі скриптів TagTime, та є сенс не відхилятись від нього. А тестова проба — просто створювалась на поточний час зі спеціальною приміткою.

🗃️ Але “тестова проба” була функціональним баластом та тільки створювала ускладнення (наприклад, її треба прибирати з усіх статистичних запитів.) Тому знайшов кращий спосіб: під час першого запуску я буду генерувати до тижня старих проб. З ними можна не тільки погратися, а й зрозуміти частоту проб, випробувати автозаповнення з Apple Health (та запросити дозвіл для нього!) та отримати перші результати.

💬 Також випробовую TipKit. Це цілий фреймворк для підказок. Не просто для того, щоб їх показати (але це теж), а відстежити, які підказки вже були закриті, а також в який момент їх пора показати. Наприклад, підказку про улюблені теги має сенс показувати, коли тегів буде принаймні 5. Цікавий взагалі фреймворк — адже підказки потрібні всім.


30.12.2024

Дев-адвент 30: TipKit

Сьогодні накидав більше порад з TipKit та продовжую бути ним вражений. До речі, ось гарне викладення всіх можливостей, а я поки поділюся власними думками.

Колись на роботі ціла команда робила інтерактивний “підручник” для одного з продуктів. Це був, фактично, ще один застосунок, який показував поверх головного продукту всілякі підказки та поради та відстежував твій шлях навчання. Ось TipKit мені й нагадує цей застосунок, тільки вже готовий. В нього і база своя є, і інтерфейс, і рушій логіки — повний комплект.

Відразу хочеться розставити ці поради просто на кожному кроці. Принаймні для онбордінгу це навіть має сенс — бо замість традиційних слайдів (які мені робити та підтримувати буде важко) я вкраплю інструкції прямо в інтерфейс. Та як окрема перевага - інтерфейс не буде надто порожнім.

Наприклад: замість типового слайду “дозволь нам надсилати сповіщення” показую пораду на кшталт: “тут ти бачиш крайню пробу, але вона вже минула… а щоб побачити наступну вчасно, увімкни сповіщення”. Або “ось 10 порожніх проб за ніч… якщо дозволити доступ до Apple Health, ми їх автоматично протегаємо.” Органічно та зрозуміло.


31.12.2024

Дев-адвент 31: воно живе!

🎁 Настав час поділитися застосунком. На публічний випуск він ще не готовий (та й маркетингові матеріали теж). Але базовий функціонал весь в нормі — я проробив онбордінг, увімкнення всіляких дозволів і таке інше — тому його вже точно пора запускати в бета-тестування.

⏰ Зупинився на короткій назві: Ping!. Насправді я цю назву бачу вже місяцями як заголовок сповіщення, та нічого кращого не уявляю. Значок застосунку все ще тимчасовий.

Так що сьогодні я ще встиг перейменувати всі ресурси застосунку, а ще змінити назву моделі Sample на Ping. Це майже тривіальна заміна по коду, єдине, що довелося експортувати та наново імпортувати власні дані в новий застосунок (бо перейменування — це ж фактично створення нового застосунку.)

🚚 Багато чого ще залишилось доробити. Я не планую зупинятися, хоча точно доведеться приділити час іншим справам (та іншим темам для каналу, хе-хе.)

🧪 Доєднатися до TestFlight можна за посиланням. На жаль, про що я забув — перед розповсюдженням застосунку на TestFlight він повинен пройти перевірку від Apple. Тому посилання наразі не пускає. Не впевнений, що це відбудеться сьогодні, але як тільки пройде перевірку, так відразу й посилання запрацює. 🧘

❄️ З прийдешнім Новим Роком вас!