tgindex
iOS Broadcast

Подборка новостей и статей для iOS разработчиков. Новости Kotlin и мультиплатформы @kotlin_broadcast Новости Android @android_broadcast Реклама и прочее @ab_manager

Последний пост
14 авг.
Последнее чтение
15:40
Постов за неделю
9
Всего постов
43
Тип
открытый
Язык
русский
Категория
Технологии
В каталоге с
12 авг.
Подписчики
3 504
−4 за 4 дн.
Сутки
−2
−0,06%
Неделя
 
Месяц
 
Просмотров на пост
1 058
40 постов
Вовлечённость
30,2%
к подписчикам
Постов в день
1,3
всего 43
Упоминаний
3
каналов
Охват размещения
оценка
1/24сутки в ленте
780
1/48двое суток
893
1/72трое суток
964

Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.

Посты

  • 📱 Как заставить SwiftUI делать красивые переносы Обычно статьи про текст рассказывают то как быстро и точно рассчитать размер контейнера, но тут более редкая проблема - некрасивые переносы слов. Случай, когда текст красиво выглядит почти на всех размерах экрана, а потом на каком-нибудь iPhone последняя строка внезапно состоит из одного-двух слов. Понятная логика, перенести это слово на предыдущую строку не понятно как описать без костылей вставки переносов в исходный текст, ведь стандартный Text не даёт нормального контроля над такими переносами. В статье интересный подход: использовать AttributedString и управлять правилами переноса через paragraph style. В частности, можно задать lineBreakStrategy и использовать .pushOut, чтобы SwiftUI старался не оставлять слишком короткую последнюю строку. Получается довольно приятная штука: 🟢не нужно вручную вставлять \n 🟢не нужно делать разные варианты текста для разных устройств 🟢перенос остаётся адаптивным И это хороший пример того, как иногда проблема SwiftUI находится не в самом Text, а уровнем ниже, в типографике и AttributedString. При этом есть важный нюанс: Не стоит пытаться запретить любые короткие строки. Иногда перенос действительно является правильным, а попытка любой ценой выровнять текст только ухудшит результат. Статья меня зацепила даже не самой идеей решения, а концепцией: типографику тоже можно сделать частью layout-поведения. И если текст выглядит странно только на некоторых размерах экрана, возможно, не нужно добавлять ещё один frame(). Сначала стоит посмотреть, какие правила переноса вообще используются.

  • видео или голосовое, без подписи

  • 🐥 @FocusState в SwiftUI Давайте базовую тему - фокус в SwiftUI.  @FocusState позволяет хранить состояние фокуса прямо в SwiftUI и управлять им из кода. Например, можно описать поля формы: 🟡имя🟡email🟡пароль. После чего можно переключать фокус между ними после ввода. Это можно сделать через enum: enum Field { case name, email, password } А затем привязать его к focused(...) В итоге логика становится довольно читаемой: 🟢открыть экран и сразу поставить фокус на поле 🟢нажать далее и перейти к следующему 🟢после ошибки вернуть пользователя к нужному полю 🟢скрыть клавиатуру, сбросив focus в nil @FocusState лучше воспринимать именно как состояние UI, а не как часть бизнес-логики. Не нужно тащить информацию о том, какое поле сейчас активно, в модель или сервис. Фокус относится к интерфейсу. Но не стоит использовать несколько независимых @FocusState, когда все поля относятся к одной форме. Обычно один enum для всей формы получается проще и предсказуемее. Магия @FocusState лежит не только в упрощении работы с формами, это подход по делегированию поведения системе. Это особенно актуально, если интерфейс по-настоящему кросплатформенный и работает не только на iOS/iPad, но и на mac или даже Apple TV. Вместо becomeFirstResponder, ссылок на UIKit и ручного управления клавиатурой достаточно описать: какое поле сейчас должно быть в фокусе и дальше SwiftUI сам занимается остальным.

  • видео или голосовое, без подписи

  • видео или голосовое, без подписи

  • видео или голосовое, без подписи

  • видео или голосовое, без подписи

  • видео или голосовое, без подписи

  • 🆓 Типобезопасные JSON в StructuredQueries Оч интересное обновление вышло у библиотеки StructuredQueries. Сама библиотека разработана Point-Free предоставляет набор инструментов, которые позволяют вам писать типобезопасные, выразительные и компонуемые SQL-выражения на языке Swift. Но данное обновление расширяет DSL на JSON и JSONB ( это тип данных, который хранит JSON-документы в оптимизированном бинарном формате). Элегантный DSL для указания типа для сериализации в таблице: @Table struct Trip: Identifiable { let id: UUID var name = "" @Column(as: Location.JSONRepresentation.self) var location: Location } Вот так будет выглядеть запрос местоположения поездки, хранящейся в столбце JSON: @Selection struct Location: Codable { var latitude = 0.0 var longitude = 0.0 } При применении макроса @Selection к Location структура типа становится видимой для builder-а запросов, и дает возможность перемещаться по JSON с помощью метода jsonExtract и привычного пути к ключу в Swift: Trip.where { $0.location .jsonExtract(\.longitude) < 0 } // Превращается в SQL SELECT … FROM "trips" WHERE json_extract( "trips"."location", '$."longitude"') < 0 Это означает, что вы получаете безопасность схемы для столбцов вашей таблицы, для полей внутри ваших JSON-данных и для извлекаемых значений. И эти выражения можно использовать в любом месте запроса: where, select, order в полях и т. д. Вы также можете обновлять данные в формате JSON непосредственно в базе данных, не загружая их в память, используя jsonSet, jsonInsert, jsonAppend, jsonRemove и jsonReplace: Profile.update { $0.author = $0.author .jsonSet(\.name, "Blob") } // превращается в UPDATE "profiles" SET "author" = json_set( "profiles"."author", '$."name"', 'Blob' ) Profile.update { $0.tags = $0.tags .jsonAppend("new") } // превращается в UPDATE "profiles" SET "tags" = json_insert( "profiles"."tags", '$[#]', 'new' ) Не сказал бы что работа с SQLite напрямую часто требуется, но во-первых это красиво 😀 . А Во-вторых можно взять на вооружение такой подход для создания своих DSL для работы с JSON 😺️ MR со всеми доработками и тестами

  • 7 авг.953220

    🐥 Почему @MainActor и протоколы в Swift 6 могут поссориться В теории всё просто, есть протокол: protocol ImageLoader { ... } Реализация, которая работает с UI: @MainActor final class ImageLoaderImpl: ImageLoader { ... } Но Swift 6 начинает задавать неприятный вопрос: а сам протокол изолирован от Main Actor или нет? И вот тут начинается самое интересное. @MainActor на конкретной реализации не означает автоматически, что любой код, который работает с протоколом, тоже находится на Main Actor. Для компилятора протокол может использоваться совершенно независимо от конкретной реализации. В результате вполне невинный код начинает упираться в ошибки concurrency: 🟡Вызов main-actor метода из nonisolated контекста 🟡Несоответствие требований протокола и actor isolation 🟡Необходимость добавлять @MainActor туда, где раньше его вообще не было Особенно часто это всплывает при dependency injection. Например, ViewModel хранит зависимость как: let loader: ImageLoader а конкретно переданный ImageLoaderImpl является @MainActor. Swift должен гарантировать, что контракт ImageLoader сам по себе безопасен. И здесь есть несколько вариантов: ➡️ Можно сделать весь протокол @MainActor ➡️ Можно изолировать только отдельные методы ➡️ Можно использовать nonisolated, если конкретная операция действительно не зависит от Main Actor И вот последний вариант особенно важно не использовать просто для того, чтобы "заткнуть компилятор". Если метод реально работает с состоянием, которое должно жить на Main Actor, nonisolated проблему не решает. Он просто заставляет вас взять ответственность за безопасность на себя. Попробую подытожить: @MainActor — это не просто атрибут класса. Это часть контракта, и при работе через протокол этот контракт должен быть виден там, где он действительно нужен. Поэтому при проектировании Swift 6 API стоит заранее решить: 🟢Весь сервис main-actor isolated? 🟢Только часть его методов? 🟢Протокол вообще должен знать про actor isolation? 🟢Можно ли использовать dependency без Main Actor? Это особенно важно для архитектуры с ViewModel + protocols + dependency injection. Это со SwiftUI как раз очень распространено. Раньше можно было сказать: «Ну эта реализация всё равно работает на Main Actor». Swift 6 отвечает: «Мне всё равно. Я проверяю контракт». И, пожалуй, это хорошая новость. Компилятор наконец заставляет нас явно описывать, где именно должен выполняться код, вместо того чтобы надеяться, что конкретная реализация всё разрулит сама

  • 3 авг.1 28214

    видео или голосовое, без подписи

  • 3 авг.1 32414

    видео или голосовое, без подписи

  • 3 авг.1 28414

    видео или голосовое, без подписи

  • 3 авг.1 28014

    видео или голосовое, без подписи

  • 3 авг.1 212614

    🎯 Новый уровень работы с фото и видео Рассматриваем новый фреймворк — Media Intelligence. Если совсем коротко, это API, которое позволяет приложению понимать содержимое фото и видео, а не просто отображать их. Например, определить: 🟣что происходит в кадре 🟣какие объекты есть на изображении 🟣какие сцены встречаются в видео 🟣где начинается нужный момент 🟣какие фрагменты похожи друг на друга Apple постепенно начинает повышать уровень абстракции при работе с AI и делиться внутренними моделями. Появляется абстракция, благодаря которой Apple сможет подменять реализацию. Гораздо важнее становится какую задачу нужно решить. Раньше для поиска нужного момента в видео приходилось строить собственный пайплайн, теперь система сама может помочь понять, что находится в медиаконтенте. Новые API работают локально, без необходимости встраивать огромные модели в приложение. Очень похоже что все то что уже обкатали в команде Photos становится доступно всем, как только API удалось стабилизировать. Полезные ссылки: ➡ iOS 27: Media Intelligence Framework ➡ Media Intelligence Framework Documentation

  • 30 июл.1 37123

    видео или голосовое, без подписи

  • 30 июл.1 317723

    🐥 Swift 6 стал заметно дружелюбнее к Concurrency Продолжаем эксперименты с многопоточностью в Swift 6, в этой области мы точно движемся в правильном направлении. Одна из главных претензий к Swift 6 звучала примерно так: Я просто включил Swift 6, а компилятор решил переписать половину моего проекта. Sendable, @MainActor, изоляции, десятки новых предупреждений... И вроде всё правильно, но начать миграцию было больно. Именно поэтому Apple представила Approachable Concurrency. Идея очень простая. Вместо того чтобы сразу требовать идеальный concurrency-код, компилятор позволяет включать проверки постепенно. Мы получили преимущества новой модели, но без ощущения, что проект нужно переписать за один раз. Многие типы из UIKit и SwiftUI уже аннотированы так, что с ними стало проще работать, часть проверок теперь включается только тогда, когда они действительно приносят пользу. Но Approachable Concurrency — это не способ избежать миграции, а способ сделать её управляемой. Если в коде есть потенциальные race condition или нарушение изоляции акторов, рано или поздно их всё равно придётся исправить. Радует что в этой области Apple приняли тот факт, что iOS-приложения не всегда пишутся с нуля и нужно заботиться и о разработчиках которые поддерживают свои приложения годами. Гайды от Apple по миграции: ➡Embracing Swift Concurrency ➡Enabling Complete Concurrency Checking

  • 29 июл.1 19224

    видео или голосовое, без подписи

  • 29 июл.1 23024

    видео или голосовое, без подписи

  • 29 июл.1 22724

    видео или голосовое, без подписи