iOS Broadcast
3.54K subscribers
1.97K photos
87 videos
1.08K links
Подборка новостей и статей для iOS разработчиков.

Новости Kotlin и мультиплатформы @kotlin_broadcast
Новости Android @android_broadcast
Реклама и прочее @ab_manager
Download Telegram
💻 Apple представила MacBook Neo — самый доступный ноутбук Mac
Apple показала новый MacBook Neo — «входной билет» в мир Mac с чипом A18 Pro и ценой от 599$ (499$ для образования). Упор — на дизайн, автономность и «достаточную» мощность для повседневных задач и AI‑фич.

Ключевые факты:
🟢Алюминиевый корпусе и яркие цвета
🟢Дисплей 13″ Liquid Retina
🟢Чип A18 Pro, тот же что и в iPhone (Мощнее чем M1)
🟢В базе 256GB и нет Touch ID за 599$
🟢За 512 и Touch ID прийдется доплатить 100$, такой ноут стоит уже 699$
🟢Два порта Type‑C USB 3.0 до 10 Гбит/с и USB 2.0 до 480 Мбит/с, какой где предстоит угадать
🟢Автономность До 16 часов работы от батареи
🟢Ввод и управление Magic Keyboard, Multi‑Touch trackpad
🔴от 599$
По сути, MacBook Neo — это «народный» MacBook для студентов, школ и тех, кому нужен первый Mac для базовой работы, учёбы и лёгкого креатива, но с акцентом на современный дизайн, автономность и встроенный AI. Очень много железа по цене iPhone
Продажи стартуют 11 марта.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍1
MacBook Pro (13-inch, Late 2011)
Неделю новинок от Apple захотелось закончить небольшой ретроспективой. Историей о моем первом Macbook и тех фишках и внимании к деталям, которое мы потеряли вместе с эрой скевоморфизма.
Это уже эпоха Unibody корпуса, но еще не Retina дисплей, корпус толстый и легко поддается апгрейду. Личное ощущение: тогдашние макбуки были объектом, а не просто ноутбуком

Фишка #1: «Дыхание» — pulsating sleep indicator
Белый светодиод, который "дышал" во сне, реализация поражала, металл в нужном месте истончили и перфорировали микроскопическими отверстиями. Паттерн моргания соответствовал человеческому дыханию во сне. Создавалось ощущение, что у ноутбука есть пульс и он действительно живет

Фишка #2: Светящееся яблоко
Подсветка логотипа осуществлялась за счёт подсветки матрицы, не отдельным светодиодом. По сути — чистый бренд и эстетика, но она породила целую культуру (стикеры, «чехлы с вырезом», вплоть до шуток в сериалах). Для разработчиков это был социальный маркер профессии. А при работе в тёмной комнате светящийся логотип был частью «атмосферы» при работе.

Фишка #3: Инфракрасный порт
Это был последний ноутбук который работал с пультом Apple Remote, я его даже покупал для управлениями Keynote. Тогда MacBook часто выступал и как медиаплеер в гостиной и IR‑порт был логичным. С появлением AirPlay и iOS‑пультов IR умер как класс

Фишка #4: Встроенный оптический привод (SuperDrive)
DVD‑фильмы, установка софта с дисков, запись дисков (CD/DVD) под проекты, музыку, бэкапы (до массового облака). Это был важный момент: "всё с собой" — ноут был автономным центром работы и медиа без внешних свистоперделок.

Фишка #5: Кнопка и индикатор уровня заряда на корпусе
Маленькая кнопка + линейка LED‑точек сбоку. Использовалась только чтобы посмотреть заряд без включения ноутбука, не открывая крышку. Это использовалось для быстрой проверки перед выходом, хватит ли на встречу. Сейчас это кажется мелочью, но UX был очень приятным и физически понятным.

По технических характеристикам этот ноутбук ничем не выделялся:
🔵Двухъядерный itel i5
🔵500GB жесткий диск 5400 оборотов
🔵DVD SuperDrive, который сразу заменялся на SSD
🔵4 GB Ram, которые легко дополнялся до 16 GB
🔴Тогда он стоил 40к в РФ и 999$ в US

В 2013 году уже были Retina ноутбуки, но этот был самый дешевый и именно по-этому я его и купил. А теперь
самый дешевый - MacBook Neo. Есть ли в нем "душа", решать тем кто его купит. Мне немного жаль что внимание к таким мелочам и их осознанный дизайн остались лишь частью истории Apple. Какой ноутбук запомнился вам?
P.S. Первое фото из личного архива
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
18👍5
TDD в мире AI: тесты как язык общения с моделью
Ссылки в этот раз не будет, чисто мое мнение. Вообще, я давний фанат TDD подхода, классический TDD - это сначала тест, потом код. Это сильно забустило в свое время меня и как инженера (написание тестов перед кодов позволяют задумываться о архитектуре до написания кода) и как продакта (продумываение требований и граничных условий для написания тестов позволяет продумать многие аспекты, которые всплывали у многих только ближе к тестированию). В мире, где код всё чаще пишет AI, формула меняется, но суть та же: тесты задают правила игры.

Тесты как протокол общения с AI
Обычно взаимодействие с моделью выглядит так:
Создай модуль для работы со списком...
магия
Получаем код, который «вроде работает».

Но не знает, где у вас деньги, регуляторика, странные бизнес‑правила и больные edge‑кейсы.

Работа с AI-TDD
1. Сначала пишем тест-кейсы, можно использовать на этом этапе AI, он уже не плохо справляется с этой задачей, особенно при наличии ТЗ а не только пользовательского сценария
2. Просим агента написать тесты исходя из тест-кейсов, тут важно проверять самостоятельно соответствие тест-кейсам и предупредить модель что вы работаете по TDD и тесты должны опираться на модели и будут красными
2. Даём промпт в духе:
«Вот набор XCTest‑кейсов. Напиши/обнови реализацию так, чтобы все они проходили. Код можно менять как угодно, но сигнатуры публичных методов оставь.»

Роль тестов здесь меняется:
это уже не «страховка на потом», а контракт, который мы предъявляем модели.

В классическом цикле TDD:
red → green → refactor

С AI он становится больше похож на:
test → prompt → code → run tests → new prompt / refactor

Мини‑флоу на примерной задаче:

1. Формулируем поведение через тесты
Например, парсер промокодa, калькулятор скидки, валидатор формата.
2. Отправляем в AI:
🟣описание задачи
🟣список тестов
🟣ограничения (Swift, без сторонних зависимостей, таргет iOS такой‑то).
3. Генерим реализацию и гоняем тесты.
🟣что упало — идёт обратно в модель
4. Итеративно уточняем промпт, пока не станет зелёным:
🟣добавляем новые кейсы в тесты, если понимаем, что что‑то не учли;
🟣ужесточаем формулировки («не используй force‑unwrap», «без глобального состояния»).

Фокус смещается:
важно не то, кто написал конкретную строку кода, а насколько хорошо мы задали контракт и тестами, и промптом.
Что мне еще нравится в таком подходе с тестами, так это обесопашивание своего кода от вмешательства. В больших проектах нет твоего кода, есть блоки которые ты можешь ревьювить и если твой блок достаточно большой, то достаточно отслеживать изменение в тестах и если при изменении кода тесты не менялись и прошли, значит, как минимум, ничего сломаться не должно.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🤔2
🐥 Фишки Swift, о которых многие забывают
Swift оброс синтаксическим сахаром, и часть классных фич теряется в шуме. По мелким фишкам даже пишутся целые статьи, но гораздо полезнее перечитывать официальный гайд по языку. Собрал для вас несколько фишек, какие сам часто использую:

1. Паттерн‑матчинг в switch
let value: Int? = Int.random(in: 0...10)

switch value {
case let .some(v) where v > 5:
print("Большое число: \(v)")
case let .some(v):
print("Маленькое число: \(v)")
case .none:
print("nil")
}

let .some(v) — это как if let, но прямо внутри switch, плюс можно сразу вешать дополнительные условия через where

2. Нюансы работы со строками
Со строками в Swift раньше было больно работать, но у стандартной библиотеки есть несколько новых фишек:
🔵Безопасные индексы вместо str[i]
let s = "Привет"

let firstIndex = s.startIndex
let secondIndex = s.index(after: firstIndex)
let secondChar = s[secondIndex] // "р"

🔵Срезы:
let prefix = s.prefix(3) // "При"
let suffix = s.suffix(2) // "ет"

🔵Реальная задача - обрезать строку до N символов и добавить многоточие:
func truncated(_ string: String, limit: Int) -> String {
guard string.count > limit else { return string }
let endIndex = string.index(string.startIndex, offsetBy: limit)
return String(string[string.startIndex..<endIndex]) + "…"
}

truncated("Привет, мир!", limit: 6) // "Привет…"

🔵Вместо NSRange/NSString давно можно обойтись чистым Swift:
let text = "https://example.com - мой сайт"
if let range = text.range(of: "https://") {
let prefix = text[..<range.lowerBound] // перед URL
let urlPart = text[range.lowerBound...] // начиная с URL
print(prefix) // ""
print(urlPart) // "https://example.com - мой сайт"
}

🔵Вообще работать со строкой можно как с обычной коллекцией:
let sentence = "Hello, Swift world!"

let words = sentence
.split { $0.isWhitespace || $0.isPunctuation }
.map(String.init)

print(words) // ["Hello", "Swift", "world"]


3. Массивы
🔵Иногда нужно получить массив фиксированной длины, уже заполненный значением по умолчанию, это можно сделать через конструктор:
let zeros = Array(repeating: 0, count: 10)
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

let placeholders = Array(repeating: "—", count: 5)
// ["—", "—", "—", "—", "—"]

🔵Еще часто забывают про reduce(into:). Если обычный reduce возвращает новый массив/значение, то reduce(into:) позволяет изменять уже существующую структуру без лишних копий
let names = ["Alice", "Bob", "Eve", "Alex", "Ben"]

let grouped = names.reduce(into: [Character: [String]]()) { result, name in
guard let first = name.first else { return }
result[first, default: []].append(name)
}

// ["A": ["Alice", "Alex"], "B": ["Bob", "Ben"], "E": ["Eve"]]

По сути — мини‑groupBy на стандартной библиотеке.

🔵 zip — проход по двум массивам параллельно
let titles = ["Intro", "Chapter 1", "Chapter 2"]
let pages = [1, 5, 17]

for (title, page) in zip(titles, pages) {
print("\(title) начинается на странице \(page)")
}

🔴Здесь важно помнить: длина берётся по минимальному из двух массивов — лишние элементы отбрасываются.

🔵Срезы массивов и prefix/suffix работают и тут:
let numbers = [1, 2, 3, 4, 5, 6]

let firstThree = numbers.prefix(3) // [1, 2, 3]
let lastTwo = numbers.suffix(2) // [5, 6]

// Срез → обратно в Array при необходимости:
let firstThreeArray = Array(firstThree)

Ставь 👍 если нашел для себя что-то новое и 🤔 если знал все из этого списка
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍145🤔5🔥1
🔨 Быстрый гайд по ASWebAuthenticationSession.
Если вы задавались целью реализовать веб авторизацию или оценить задачу, то сталкивались с вопросом а как это правильно сделать. ASWebAuthenticationSession ждёт правильный URL‑callback, чтобы понять, что авторизация закончилась, и вернуть пользователя в приложение. Каждый раз приходится вспоминать, оставлю корректный гайд тут. Есть два способа:

1. Custom URL scheme
🔵Регистрируешь, например, myapp:// в Info.plist (CFBundleURLTypes).
🔵В OAuth‑провайдере указываешь redirect URI вида myapp://callback.
🔵ASWebAuthenticationSession стартуешь с callbackURLScheme = "myapp", и когда страница редиректит на myapp://..., сессия ловит URL и отдаёт его в completion:
let session = ASWebAuthenticationSession(
url: authURL,
callbackURLScheme: "myapp"
) { callbackURL, error in
// разбираем токен из callbackURL
}

🟢Плюсы: просто, минимум инфраструктуры.
🔴Минусы: не очень красиво, возможны диалоги "Открыть в myapp?"

2. Universal links (HTTPS)
🔵Вместо myapp://callback — обычный https://myapp.com/auth/callback
🔵Нужно настроить apple-app-site-association на сервере
🔵Выглядит более профессионально, URL нормальный, без кастомных схем, меньше лишних алертов
🔵С точки зрения ASWebAuthenticationSession логика та же: он ждёт редирект на твой callback‑URL и пробрасывает его в completion.
func handleCallback(url: URL) {
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
let token = components.queryItems?.first(where: { $0.name == "token" })?.value else {
return
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
⌨️ TUIkit — SwiftUI‑подобные интерфейсы для терминала
Если вы когда-то создавали приложение для терминала с UI, вы знаете, что это не просто. TUIkit — декларативный фреймворк для терминальных интерфейсов на Swift, так еще и с привычным SwiftUI DSL.
🟢Доступны основные компоненты VStack, HStack, Text, Button, ForEach
🟢Работает на macOS и Linux, без ncurses и C‑зависимостей — только чистый Swift
🟢Есть готовые компоненты (Panel, Card, Dialog, Alert, Menu), темы с RGB‑цветами, фокус‑менеджмент и статус‑бар с шорткатами

🔖Сайт: https://tuikit.dev
⭐️ GitHub: https://github.com/phranck/TUIkit
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥4
🔨 NSCache как базовый инструмент in‑memory кеширования на iOS
Забытый старичок NSCache - контейнер для in‑memory кеша в iOS c iOS 4, он сам умеет освобождать память по требованию системы и отлично себя зарекомендовал для этой задачи. Он ведёт себя похоже на Dictionary, но изначально спроектирован под сценарии «ускорить, но не сломать», когда cache‑miss всегда допустим.

Что это даёт:
🟢Можно кэшировать тяжёлые объекты (разобранный rich text, изображения, результаты парсинга), не боясь утечек и переполнения памяти
🟢Система сама выкинет данные из кэша при нехватке памяти — без крашей и ручного менеджмента
⚠️ Корректность приложения не завязана на кэш: всё, что лежит в NSCache, можно безопасно пересоздать

При работе с ним в современном окружении есть нюансы:
🟣NSCache работает только с классами (AnyObject): и ключ, и значение должны быть ссылочными типами; для Int/struct‑ов нужен boxing (NSNumber или свой класс‑обёртка)
🟣В проде почти всегда стоит задавать countLimit и totalCostLimit, иначе кэш может незаметно разрастись
🟣cost — это абстрактная метрика, а не байты: для текста можно брать length, для изображений —, например, ширина × высота, не стремясь к идеальной точности

NSCache — отличный выбор для некритичного in‑memory кеширования «дорогих, но воспроизводимых» объектов внутри процесса, но для сети и данных, которые должны переживать перезапуск, его нужно сочетать с другими механизмами (например, URLCache и хранением на диске).
Please open Telegram to view this post
VIEW IN TELEGRAM
9
🔨 Xcode 26.4: тихий но полезный релиз
Apple выпустила Xcode 26.4 RC — без громких фич, но с кучей полезных доработок в Swift Testing, локализации и стабильности сборок. Что заявлено:
🟢Стабильность. Заявлены более предсказуемые сборки и диагностика для больших проектов. Меньше «рандомных» build‑фейлов и непонятных сообщений от компилятора

🟢String Catalogs: меньше боли при локализации
🔵Редактор String Catalogs стал ощутимо удобнее. Xcode 26.4 наконец закрывает базовые сценарии, которые раньше приходилось добивать руками и скриптами
🔵Можно удалять языки прямо из каталога — либо только из него, либо сразу из всего проекта
🔵При добавлении нового языка Xcode умеет предзаполнять переводы на основе существующего
🔵Появился нормальный cut/copy/paste и дублирование строк как внутри каталога, так и между ними

🟢Swift Testing получил пачку улучшений, которые важны, если вы реально пользуетесь им в проде или постепенно мигрируете с XCTest. Основной фокус — на удобстве отладки и смешанных тестовых наборах.
🔵Можно прикреплять к тестам изображения для снапшотов и визуальной проверки
🔵Вводятся уровни важности проблем (warning vs failure), чтобы не каждый баг ронял CI
🔵При падении приложения в UI‑тестах Xcode автоматически прикрепляет crash‑лог и показывает понятное предупреждение

Ну и небольшой снипет по работе со снапшотами в тестах:
import Testing
import UIKit

@Test
func testProfileAvatarRendering() async throws {
let size = CGSize(width: 80, height: 80)
let renderer = UIGraphicsImageRenderer(size: size)

let image = renderer.image { context in
UIColor.systemBlue.setFill()
context.fill(CGRect(origin: .zero, size: size))
}
#expect(image.size == size)

// В Xcode 26.4 это вложение будет видно прямо в результатах теста
#attach(image, named: "profile-avatar")
}
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍2
🈸 Liquid Glass: Apple обяжет разработчиков перейти на новый дизайн Liquid Glass с iOS 27
Похоже что крайний срок перехода приложений на жидкое стекло (по крайней мере, на встроенные элементы) - апрель 2027 года. Если вы избегали использования нового пользовательского интерфейса через ключ UIDesignRequiresCompatibility, самое время задуматься. Инсайдеры и новостные агенства сходятся в одном: Liquid Glass — не эксперимент iOS 26, а новая долгосрочная парадигма интерфейса Apple:
🔵iOS 27 принесёт больше контроля, а не отмену.
По данным Гурмана, Apple тестирует системный ползунок прозрачности для Liquid Glass (сейчас он есть только у часов на локскрине). iOS 27 должна расширить эти настройки на всю систему
🔵26.4 уже чинит самые больные места: уменьшение вспышек и бликов, более надёжный Reduce Motion для анимаций, улучшения контраста для чувствительных пользователей
🔵Доступность остаётся проблемой: профильные отчёты по accessibility критикуют Liquid Glass за ухудшение читаемости и контраста.

Что делать?
Формально Apple пока не обязывает всех перейти на Liquid Glass. Но может в любой момент объявить дату, с которой больше не будут приниматься обновления с ключем UIDesignRequiresCompatibility. Если вы еще не оценили объем предстоящей работы-крайне советую запланировать эту работу.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥3