🚗 Apple CarPlay Ultra - відгуки та ситуація на ринкуЯк ви знаєте на минулому WWDC Apple показала нове покоління CarPlay - CarPlay Ultra яке повністю заміняє бортовий компʼютер та інші системи в автомобілі. Відгуки людей:- конекшен з iPhone набагато швидший- іноді відчувається затримка/лаг на приборній панелі відносно відчуттів коли натискаєш педаль в підлогу на twin-turbo V8- UX топовий, дуже комфортно користуватися і CarPlay і клімат контролем і режимами водіння одночасно- є один відгук де екрани і бортового компʼютера і основний стали повністю чорними на значний момент часу- багато претензій до SiriЩо кажуть керівники автомобільних компаній👇Ford:Ford Motor Company раніше зобов'язалася залишитися з базовим Apple CarPlay, але вона не прийме новіший CarPlay Ultra. Розмовляючи з Джоанною Стерн у подкасті Decoder, генеральний директор Джим Фарлі каже, що багато разів розмовляв з Тімом Куком про майбутнє інтегрованих систем, але очікує, що Ford може вирішити створити власне програмне забезпечення на замовлення.
BMW:Посилаючись на так званий "міф про CarPlay", що водії використовують його значно, старший віце-президент BMW з розвитку UI/UX Стефан Дюрах наполягає на тому, що це неправда. Натомість водії BMW дійсно вважають за краще використовувати систему автовиробника.
BWSwift 📱 YouTube 📱 Patreon
Зазвичай не люблю писати про UI, бо більше тягне на тяжкий люкс у вигляді хаків та алгоритмів. Але тут екзотичний випадок =) Панове: реалізація бокових "sticky" хедерів на SwiftUI. Власне, Header знаходиться не зверху списку як заведено, а зліва або справа. При цьому його поведінка еквівалентна системним хедерам. Дизайн мого рішення напряму експлуатує системний топ хедер (власне, щоб делегувати йому більшість розрахунків), але основний виклик, що став переді мною - повністю "вирізати" його зверху, але зеберегти при цьому його логічну складову. Мої розрахунки здебільшого стосувалися поведінки бокового відображення. Бо навідміну від топ-хедера, що послідовно лежить в таблиці, боковий варіант лежить безпосередньо на рівні контенту, та не перекриває його. Створення такої таблиці умовно виглядає так: SideHeaderList(data: days) { day in ForEach(0..<4, id: \.self) { index in item(for: day, index: index) }} header: { day in header(for: day)}.padding(.horizontal)
А повна реалізація складая лише 50 строк чистого SwiftUI коду. Планую трохи привести його до ладу та опенсорснути. Коли зроблю це, викачу з окремим дописом. Фан факт: за версією ChatGPT, подібних реалізацій інтернет не знає.Ну а поки, діліться ідеями, як би ви реалізовували подібний компонент, та яким бачите його практичне використання! Може вкраду декілька ідей =)------------------------------Я часто пишу і писав різні здебільшого технічні цікавинки на моєму Linkedin. Можеш підписатися, якщо було цікаво =)
👩💻 Еволюція екосистеми серверного SwiftSwift давно вже не просто мова для iPhone і Mac. Swift.org показав, як сильна екосистема серверних рішень збирається об’єднати розробку клієнт‑сервісів у єдиній мові.https://swift.org/blog/swift-on-the-server-ecosystem/⚙ Що нового та цікаво:- Стандартизація API: активне обговорення та узгодження спільних специфікацій для HTTP, Middleware, вебсокетів — щоб усі Swift-сервери спілкувалися на одному “діловому англійському”.- Підтримка рендерів серверного Swift: тобто Swift може використовуватися для генерації HTML або інших представлень сервером (SSR), ще ближче до фреймворків як Node+React.- Мультиплатформеність: підтримка Linux — центральне завдання. В екосистему входять пакети та інструменти, які працюють на Ubuntu, CentOS і інших дистрибутивах.- Енергозбереження та продуктивність: оптимізації I/O, кешування, робота з Event Loops та асинхронністю — усі фокуси на latency, throughput та стабільність під навантаженням.- Інтеграція з існуючими мовами: можливість взаємодіяти з бібліотеками на C, C++, Python — щоб не переписувати весь стек, а поступово впроваджувати Swift.🗣️ Я б не казав, що Swift вже замінює Go чи Node в продакшені, але він точно перетворюється з “хобі” у технологічну альтернативу, яку варто моніторити, якщо ти айтішник з амбіціями.І так, колись Swift був лише для UI-кнопочок. А тепер - можливо, для всього.BWSwift 📱 YouTube 📱 Patreon
👩💻 Apple заборонила розповсюдження iTorrent навіть з альтернативних сторів - The Verge Відповідно до законодавства ЄС, Apple зобов'язана надати своїм користувачам більше свободи для встановлення додатків, які не є в офіційному App Store. Це полегшує доступ до програмного забезпечення, яке зазвичай заборонено Apple, включаючи популярний клієнт iTorrent BitTorrent. Клієнт iTorrent створив стабільну базу користувачів за останній рік, але це раптово закінчилося, коли Apple вирішила відкликати альтернативні права розробника на розповсюдження.У липні кілька користувачів поскаржилися, що не змогли завантажити iTorrent з AltStore PAL. Спочатку причина проблеми була незрозуміла, але розробник програми, XITRIX, пізніше підтвердив, що сама Apple втрутилася.Очевидно, Apple відкликала право розробника на "альтернативне розповсюдження", яке потрібно для публікації додатків в альтернативних магазинах, включаючи AltStore PAL.ℹ️У заяві The Verge прес-секретар Apple Пітер Аджем'ян сказав: "Нотарісне засвідчення цього додатка було знято, щоб дотримуватися правил, пов'язаних з урядовими санкціями, у різних юрисдикціях. Ми повідомили про це розробнику".Apple не зв'язалася з розробником до відкликання програми, і знадобилося більше місяця, щоб надати будь-які пояснення.Розробник програми каже, що цей крок був здійснений без попередження, без пояснень і без можливості подати апеляцію, фактично відрізавши доступ до легального інструменту торрентування, який набув популярності по всій Європі за останній рік.
🗣️Ось так одним днем Apple може заборонити будь-який додаток навіть з альтернативних сторів.BWSwift 📱 YouTube 📱 Patreon
Нещодавно я зарепортив багу Swift компілятора https://t.me/bwswift/1912, і ця історія отримала завершення.Моя issue була офіційно визнана багом, виправлена і замержена.І хоч в моїх мріях я хотів отримати KeyPath який вміє вказувати на підтип, але виправлення крашу компилятора в будь яку сторону це добре, бо краш компілятора це однозначно баг. Код має або працювати, або компілятор мусить надати опис помилки.Тож, тепер ми матимемо помилку замість крашу, яку зможемо бачити також в редакторі Xcode 🥳This change adds detection for nested type references in KeyPath componentsand applies the appropriate fix to generate meaningful error messages,following the same pattern already established for method references.The fix ensures that invalid KeyPath references fail gracefully in normalmode and provide helpful diagnostics in diagnostic mode, improving thedeveloper experience when working with KeyPaths.
Issue on GitHub:https://github.com/swiftlang/swift/issues/83197LinkedIn Post:https://www.linkedin.com/posts/activity-7366673341526478849-fj-W
💡Стан штучного інтелекту в бізнесі 2025 - ініціатива NANDA від інституту MIT опублікувала нові результати дослідження.Декілька коротких цитат 👇Незважаючи на поспіх інтегрувати потужні нові моделі, близько 5% пілотних програм штучного інтелекту досягають швидкого прискорення доходів в компанії; але переважна більшість зупиняється, забезпечуючи незначний або взагалі не вимірюваний вплив на P&L.
Простими словами - 95% зусиль на впровадження ШІ в компанії не призвели ні до чого.Як заявив анонімний директор з інформаційних технологій в інтерв'ю з авторами: "Ми бачили десятки демок цього року. Можливо, одна чи дві дійсно корисні. Решта - це обгортки або наукові проєкти".
Простими словами - людям подобається як іграшка, але не знають куди приткнути."Здається, немає жодних звільнень. ... Робочі місця, які найбільше постраждали, вже були низькопріоритетними або передані на аутсорсинг", - розповідає Axios Адітья Чаллапаллі, дослідник проекту NANDA в Массачусетському технологічному інституті.Замість заміни працівників, організації отримують реальні вигоди від "заміни BPO [аутсорсингу бізнес-процесів] та зовнішніх агентств, а не скорочення внутрішнього персоналу", згідно зі звітом.
Простими словами - компанії стали менше аутсорсити роботу, яку тепер можуть перекласти на штучний інтелект. Просто розривають контракти з аутсорсерами.95% організацій, які інвестують у генеративний штучний інтелект, отримують нульову віддачу від цих інвестицій.
Простими словами - керівники компаній повірили в сказку про ШІ і просто втратили багато грошей на його адаптацію, яка так і не запрацювала як хотілося.BWSwift 📱 YouTube 📱 Patreon
Хочу поділитися простим, але ефективним трюком зі Swift. Чи мали ви коли-небудь необхідність зафейкати дані в структурі, до параметрів якої ви не маєте доступ? Наприклад, якась публічна структура, але з приватним інітом в якомусь сторонньому пакеті. Ви можете створити фейкову структуру з ідентичною бітовою комбінацією та зкастувати її у потрібний тип! Все що потрібно: - знайти порядок і типи полів.- створити фейкову структуру з ними у правильній послідовності. - використати unsafeBitCast для трансформації нашого фейку у потрібний тип. let fake = (10, "World", true)let hacked = unsafeBitCast(fake, to: Original.self)
Чи це безпечно? Ні. Чому це небезбечно: - структури в Swift не гарантують стабільний layout памʼяті. - наприклад, String не є типом з фіксованим розміром, і тому його представлення в памʼяті може відрізнятися від очікуваного. - цей трюк повністю обходить логіку типів в Swift та логіку, можливо закладену для оригінального типу, що може призвести до неочікуваних результатів. Це цікавий трюк з памʼяттю, але непридатний до проду, бо порушує типобезпечність. Практичне застосування таке: - Тестування структур з приватним ініціалізатором чи полями. - Реверс та дослідження приватних API (приклад на 2му скрині). P. S. На другому скрині приклад, як подібним способом можна фейкнути View в SwiftUI. Наприклад, вкинувши Bool в закриту проперті isSecure у TextField. Агресивно 😅------------------------------Я часто пишу і писав різні здебільшого технічні цікавинки на моєму Linkedin. Можеш підписатися, якщо було цікаво =)
Помічали, що всередині блоку Task throwing функції не потребують виконання через do-catch? Якщо так, то можливо ви помічали, що навіть фейл у throwing операції НЕ призводить до крашу всередині Task? Ну, в деякому сенсі всеж таки призводить. Давайте розбиратися. Така поведінка може видаватися контрінтуітивною на перший погляд. В синхронном коді необроблена помилка з try зазвичай призводить до крешу. Ба більше: зазвичай такі операції ВИМАГАЮТЬ огортання в do-catch або опціональну огортку. Але всередині Swift Concurrency Task логіка відрізняється. Дехто в мережі вважає це помилкою розробників, недопрацьованим моментом. Але мені задум зрозумілий: ви все ще маєте змогу опрацювати помилку всередині Task через do-catch, але якщо ви цього не робите, Swift припускає, що ви навмисно закладаєте логіку відміни Task. Тобто, Task на моменті помилки необробленої try просто відміняється. Тихо, непомітно, без крашу, без логів. Ви все ще можете отримати краш, якщо явно викличете force-unwrap (try!), чи просто пропустити фейлову ділянку через опціонал (try?), або можете спіймати помилку через do-catch. Чому така поведінка можлива? Тут все просто: закенселити асинхронний блок коду - відносно очікуваний сценарій за замовчуванням, що потенційно є безпечною реакцією. ------------------------------Я часто пишу і писав різні здебільшого технічні цікавинки на моєму Linkedin. Можеш підписатися, якщо було цікаво =)
🗣️ Робочі історіїЗапустив Remote Agent, щоб він на фоні займався фіксом маленького бага і одна із інструкцій була:"напиши спочатку тести та перевір що вони фейляться і баг дійсно присутній, після цього зроби фікс і переконайся, щоб тести проходили"
Через 20 хвилин вирішив перевірити як він там поживає і побачив, що він застряг в дебагінгу, кучу логів в коді і він не може пофіксити проблему 👉 бо тести фейляться що з фіксом що без Проблема була в тому, що декілька різних даних змінюються в одній транзакції при роботі з БД і тому більш пізня логіка не бачить змін в БД, бо транзакція ще не закінчилась і дані ще не записалися, тому стандартний фетчінг далі по коду їх не бачить.Зупинив його і пишу чисто з цікавості (без засудження): "Чому вибрав priming замість розділення на транзакції", - на що він мені відповів, що дійсно аналізував таку можливість, потім розписав ряд припущень, які були на початку, і чому вони виявилися не вірними. Після цього він повністю відкидує його існуюче рішення (яке не працює), чистить git та починає реалізацію з нуля з новим підходом 🤯.💡Для мене це стало сюрпризом, бо за останні пів року активного використання AI в роботі, я не бачив такої поведінки. Зазвичай, на питання "чому", він просто відповідає, чому було вибране саме таке рішення з поясненнями, але тут він повністю вирішив відмовитися від свого рішення і піти іншим шляхом. Це дуже круте оновлення, з таким підходом стає набагто комфортніше працювати з LLM, коли ШІ може дійсно вибрати інший шлях і викинути існуюче рішення, яке він вже почав. Можливо в найближчому майбутньому, він зможе сам пробувати різні рішення, якщо застрягає на чомусь одному, це надасть набагато більшої автономії для ШІ.Це вже відчувається як майбутнє вже тут, бо ШІ самостійно:- вирішив реалізувати інше рішення, коли у нього не вийшло реалізувати першу задумку- сам вичистив git- написав нову реалізацію- сам заранив білд і тести- залив зміни та створив PR- відписався в тікеті- заверіфікував пайплайн, одна таска з CI/CD зафейлилась- пішов в CircleCI та подивився конкретну причину (код ковередж зафейлився)- дозалив фікс🤖І це все ШІ зробив автономно, єдина моя інтеракція - це питання чому вибрав такий солюшен. П.С. Саме в цьому випадку це була Claude 3.5 Sonnet через Augmеnted CodeЦе ще Junior чи вже Middle розробник?BWSwift 📱 YouTube 📱 Patreon
Реалізація зваженого рандому на Swift!В Swift рандомний вибір з колекції простий - викликаєш arr.random і погнали. Але що робити, якщо є потреба надати перевагу деяким елементам над іншими? Уявіть, у вас є масив [A, B, C], і ви хочете вплинути на вирогідність рандомного вибору певного елементу. Наприлад, 20% для A, 50% для B, і 30% для C. Стандартний рандом не враховує ваги. Тому я вирішив написати функцію, яка може. Надихнув подібний функціонал у Python. >>>> От тут можна подивитися на слайди. Функція randomElement(with probs:) приймає масив коефіцієнтів ймовірностей. Послідовність елементів має відповідати послідовності оригінального масиву. Функція використовує кумулятивні вирогідності та мапить надані ваги у вихідні, що безпосередньо враховуються при рандомізації. Якщо просто, кумулятивність полягає у тому, що кожен елемент в масиві представляє суму всіх попередніх вирогідностей + поточна. Коли кумулятивний ряд зібраний, генеруємо "справжній рандом" від 0 до 1. Результатом буде перший елемент, кумулятивна вага якого перевищує "справжньо рандомізоване" значення. Ця функція чодово підійде для: - Зважених рекомендацій - показати певні продукти з більшою вирогідністю ніж інші. - Ігрові механіки- Динамічний UI Ну і ця функція (для мене) є важливим доповненям до попереднього посту (власні вектори), у контексті більш складної задачі =) ------------------------------Я часто пишу і писав різні здебільшого технічні цікавинки на моєму Linkedin. Можеш підписатися, якщо було цікаво =)