From 180 cm to 5′ 11″: A Complete Guide to Swift Measurement
💡 Если вам вдруг нужно поддерживать различные единицы измерения в своем приложении, то вот хороший гайд по работе с Measurement.
✏️ API Measurement в Swift позволяет безопасно и удобно работать с единицами измерения, обеспечивая автоматическую конвертацию и форматирование значений.
➡️ Можно выполнять математические операции с объектами Measurement, если они принадлежат одной категории единиц, что упрощает работу с данными.
➡️ Метод formatted() позволяет легко преобразовывать Measurement в удобочитаемый текст с учетом локализации, что делает его полезным для международных приложений.
➡️ Swift позволяет добавлять новые единицы измерения в существующие категории или создавать совершенно новые категории, что расширяет возможности API.
let heightMeasurement = Measurement<UnitLength>(value: 180, unit: .centimeters)
// Division with a scalar
let half = heightMeasurement / 2
print(half.value) // 90.0
print(half) // "90.0 cm"
// Addition: different units can be added; the result is in the category’s base unit
let h180cm = Measurement<UnitLength>(value: 180, unit: .centimeters)
let h1m = Measurement<UnitLength>(value: 1, unit: .meters)
let totalHeight = h180cm + h1m // 2.8 m (base unit of UnitLength is metres)
print(totalHeight) // "2.8 m"
// Comparison with automatic unit handling
h180cm < h1m // false (180 cm ≮ 1 m)
// Ranges respect units too
let range = h1m ... h180cm
range.contains(Measurement(value: 6, unit: .feet)) // false (~1.83 m is outside)
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10
Изоляция с помощью глобальных акторов в Swift Concurrency: варианты на примере @MainActor
🔍 В статье рассматриваются различные подходы к изоляции с использованием
⚠️ Ошибки, такие как разделение соответствия протоколу и реализации (например, через расширение), могут привести к потере ожидаемой изоляции, несмотря на наличие аннотаций
🔴 Аннотация
⚙️ Выбор подхода к изоляции зависит от контекста: для взаимодействия с UI лучше использовать полную изоляцию, а для повышения производительности — частичную.
@MainActor
включают полную изоляцию на уровне типа, изоляцию отдельных методов и свойств, а также частичную изоляцию через расширения.@MainActor
.@MainActor
повышает безопасность данных в многопоточной среде, но требует внимательного проектирования для предотвращения ошибок.@MainActor
protocol IUpdate {
func update(date: Date) async
}
@Observable
final class LS {
var date: Date = .now
}
// Здесь изоляцию @MainActor получит только update
extension LS: IUpdate {
func update(date: Date) async {
await internalUpdate(date: date)
}
// А здесь изоляция уже не применится
private func internalUpdate(date: Date) async {
self.date = date
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Обсуждем кейсы на митапе Яндекса по мобильной разработке
Я.Субботник — большой митап для мобильных разработчиков. В этот раз кроме докладов участников ждёт практический разрбор кейсов на PeerLab.
PeerLab — камерная встреча с экспертами Яндекса. Для неё мы отобрали актуальные темы из разработки и карьеры. Предложить кейс для обсуждения может каждый участник — приносите их в форму регистрации и приходите на обсуждение!
В Москве точно обсудим:
🔸 Kotlin Multiplatform
🔸 Карьерное развитие
🔸 Платформенные команды
🔸 AI в разработке
А в Питере:
T-Shape разработчик
🔸 Тестирование
🔸 AI в разработке
➡️ Регистрируйтесь и ищите список экспертов-участников дискуссии на сайте
Я.Субботник — большой митап для мобильных разработчиков. В этот раз кроме докладов участников ждёт практический разрбор кейсов на PeerLab.
PeerLab — камерная встреча с экспертами Яндекса. Для неё мы отобрали актуальные темы из разработки и карьеры. Предложить кейс для обсуждения может каждый участник — приносите их в форму регистрации и приходите на обсуждение!
В Москве точно обсудим:
А в Питере:
T-Shape разработчик
➡️ Регистрируйтесь и ищите список экспертов-участников дискуссии на сайте
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2👎1
Protecting mutable state with Mutex in Swift
❓
➡️ Акторы в
ℹ️ Пример класса
⚙️ Выбор между
➡️ Для использования
Mutex
в Swift
используется для защиты состояния от одновременного доступа, обеспечивая эксклюзивный доступ к защищаемым данным.Swift
удобны для асинхронного кода, но могут усложнить код, тогда как Mutex
подходит для быстрого синхронного доступа к данным.Counter
показывает, как использовать Mutex
для безопасного увеличения и уменьшения счетчика, обеспечивая защиту от гонок данных.Mutex
и акторами зависит от удобства, согласованности и намерений разработчика; Mutex
лучше подходит для простых операций без асинхронного кода.Mutex
с SwiftUI
необходимо вручную уведомлять Observable
о доступе и изменении состояния, чтобы обновления интерфейса работали корректно.class Counter {
private let mutex = Mutex(0)
func increment() {
mutex.withLock { count in
count += 1
}
}
func decrement() {
mutex.withLock { count in
count -= 1
}
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
When the Swift Debugger Lies: The Hidden Cost of Compiler Optimizations
👀 Интересный кейс произошел у автора при отладке приложения: перед выходом из функции массив оказался пустой.
❓ Swift использует оптимизацию управления памятью, что приводит к преждевременному освобождению переменных, таких как
💡 Чтобы сохранить переменные, такие как
func getUserListForAdmin() async -> NetworkResponse<[OtherUser]> {
async let type4Request = RestClient.shared.request(Constants.Network.ENDPOINT_USERS, parameters: ["userType": 4])
async let type2Request = RestClient.shared.request(Constants.Network.ENDPOINT_USERS, parameters: ["userType": 2])
let (result4, result2) = await (type4Request, type2Request)
switch (result4, result2) {
case (.success(let users4), .success(let users2)):
for user in users4 {
user.canSeeThisUsersRequests = users2.contains(where: { $0.id == user.id })
}
return .success(users4) // At this breakpoint, users2 appears EMPTY 🤯
case (.error(let error), _), (_, .error(let error)):
return .error(error)
}
}
users2
, когда они больше не нужны.users2
, используйте withExtendedLifetime(users2)
или извлеките их из switch
-выражения заранее, чтобы избежать их удаления.Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Exploring concurrency changes in Swift 6.2
ℹ️ Swift 6.2 вводит два основных изменения в параллельности: новый флаг по умолчанию
⚠️ Флаг
⚠️ С помощью
❗️ Рекомендуется включить оба новых флага для упрощения работы с параллельностью, однако важно избегать избыточного использования
nonisolated(nonsending)
и выполнение кода на главном акторе по умолчанию с помощью настройки defaultIsolation
.nonisolated(nonsending)
позволяет асинхронным функциям наследовать контекст актора вызывающего кода, что уменьшает количество ошибок компиляции и упрощает работу с параллельностью.defaultIsolation
можно установить выполнение кода на главном акторе по умолчанию для всех объектов в пакете, что упрощает разработку UI и моделей.@concurrent
, чтобы не усложнять код.actor SomeGenerator {
// not allowed
@concurrent
func randomID() async throws -> UUID {
return UUID()
}
// allowed
@concurrent
nonisolated func randomID() async throws -> UUID {
return UUID()
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍2
Swift Enums vs Structs - Picking the Best Tool for the Job
Очередная статья про выбор между Enum и структурами (классы остались за бортом🫠 )
➡️ Enums обеспечивают исчерпывающее переключение, что делает код более надежным, особенно когда состояния являются взаимно исключающими.
➡️ Structs позволяют добавлять новые случаи и настраивать стили, что делает их идеальными для систем конфигурации и стилей.
⚙️ Можно комбинировать Enums и Structs для достижения наилучших результатов, используя каждый инструмент в зависимости от конкретной ситуации.
💡 Выбирайте Enums для управления состоянием с фиксированным набором опций и Structs для хранения сложных состояний с несколькими свойствами.
Очередная статья про выбор между Enum и структурами (классы остались за бортом
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Swift 6 Refactoring in a Camera App - SLIT_STUDIO Development Log
➡️ Swift 6 требует от разработчиков учитывать новые требования к потокобезопасности, что создает сложности при миграции, особенно с фреймворками Apple.
⚙️ Разработчик
⚠️
➡️ Код приложения был перегружен, и
💡 Важно не только исправлять ошибки, но и переосмысливать структуру приложения, чтобы избежать проблем с потокобезопасностью и улучшить общее качество кода.
Megabits
успешно адаптировал приложение SLIT_STUDIO
, используя новые компоненты, такие как actor
и GlobalActor
, для улучшения структуры кода и безопасности.AVFoundation
использует GCD
, что не совместимо с Swift Concurrency
, требуя от разработчиков находить нестандартные решения для обеспечения потокобезопасности.Megabits
разделил его на более управляемые компоненты, такие как CaptureManageObject
и Recorder
, чтобы улучшить читаемость и поддержку.@globalActor actor CameraActor: GlobalActor {
static let shared = CameraActor()
}
@CameraActor class Camera: NSObject {
let captureQueue = DispatchQueue(label: "com.linearCCD.capture")
var captureSession = AVCaptureSession()
var currentDevice: AVCaptureDevice?
var videoInput: AVCaptureDeviceInput?
var audioInput: AVCaptureDeviceInput?
var videoOutput: AVCaptureVideoDataOutput?
var audioOutput: AVCaptureAudioDataOutput?
...
}
@CameraActor class CapturePipeline: NSObject, ObservableObject {
let renderContext: MTIContext
var renderPoolForFilter = RenderPool()
var renderPoolForRecordingImage = RenderPool()
var cameraFeedRenderTask: Task<(), Never>?
...
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Для чего я написал собственный аудиопроигрыватель
👀 Автор разработал собственный аудиопроигрыватель из-за неудовлетворенности существующими решениями, такими как Apple Music и сторонние приложения, которые не обеспечивали нужного функционала для управления локальной музыкальной библиотекой.
⚙️ Приложение было создано с использованием SwiftUI для упрощения разработки интерфейса и управления данными, а также SQLite для реализации полнотекстового поиска и хранения данных.
⚠️ Приложение включает в себя гибкий поиск по папкам iCloud, управление плейлистами и воспроизведение музыки с возможностью настройки очереди и управления громкостью.
🫠 Существующие приложения часто требуют подписки, имеют ограниченные функции и неудобный интерфейс, что побудило автора создать собственное решение.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Unique values in Swift: Removing duplicates from an array
❓ В
➡️
➡️ Если порядок важен, можно создать расширение для массива, которое использует протокол
👀 Выбор между
Swift
нет встроенных методов для удаления дубликатов из массива, поэтому необходимо использовать альтернативные подходы, такие как использование Set
или создание расширения для массива.Set
по умолчанию содержит только уникальные значения и подходит, если порядок элементов не важен. Это более производительный вариант для решения проблемы уникальности.Hashable
для фильтрации дубликатов, обеспечивая линейную временную сложность.Set
и расширением массива зависит от необходимости сохранения порядка элементов: используйте Set
, если порядок не важен, и расширение массива, если он важен.extension Sequence where Iterator.Element: Hashable {
func unique() -> [Iterator.Element] {
var seen: Set<Iterator.Element> = []
return filter { seen.insert($0).inserted }
}
}
print(array.unique()) // prints: [1, 2, 3]
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Как мы превратили iPhone в лабораторный микроскоп с AI и BLE: real-world edge-приложение
⚡️ Крутая статья о применении iPhone в медицине. Тут и задачи компьютерного зрения, и оптимизации кода, и работа с AI.
⚙️ Система превращает обычный лабораторный микроскоп в цифровой сканер с автоматической подачей и съемкой, используя iPhone для управления и анализа клеток крови.
💵 Разработка недорогого комплекта автоматизации микроскопа, стоимость которого составляет ~800 $, что значительно дешевле, чем традиционные автоматические системы, стоящие от 10к $.
💡 Используемые технологии включают AI для распознавания клеток, Bluetooth Low Energy для управления моторизованным столиком и мощные процессоры iPhone для обработки изображений в реальном времени.
🔥 Мобильное приложение обрабатывает видеопоток, детектирует и классифицирует клетки, управляет движением предметного столика и отправляет данные на веб-сервер для анализа.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤1
Using AI and Cursor to localize Xcode String Catalogs
❓ Строковые каталоги в
➡️ Для экспорта языка из строкового каталога выберите приложение и используйте меню
💡
➡️ После перевода, импортируйте локализованные файлы обратно в
А вот промпт, используемый автором:
Xcode
позволяют легко локализовать приложения, добавляя новые языки через интерфейс, что упрощает процесс по сравнению с использованием старых файлов .strings
.Product > Export Localizations...
, чтобы сохранить локализации в отдельные папки .xcloc
.Cursor
может быть использован для перевода файлов XLIFF
, где вы можете выбрать конкретный файл и запросить перевод содержимого, что упрощает процесс локализации.Xcode
через Product > Import Localizations...
, чтобы обновить строковой каталог с новыми переводами.А вот промпт, используемый автором:
Translate the selected .xliff file’s body tag to the target-language. For each text, keep the source tag and add a target tag with a state="translated"
attribute and the translation as body. Output the result as plain text.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Meet the Foundation Models framework
WWDC прошел и, как обычно, показали много нового и интересного (нет, особенно ужасен новый дизайн Liquid Glass). Для меня самое интересное – это новые AI инструменты и возможности и тут на самом деле было много интересного.
Apple показали фрейморк Foundation Models для работы с llm on-device в приложениях. Из основного:
- полностью нативная реализация и интеграция со swift'ом. Сама модель адаптирована под работу на Apple процессорах
- модель: 3B квантизованная до 2х бит: создать полноценного чат бота с ней не выйдет, но с задачами суммаризации, генерацией / понимаем текста и другими несложными llm-based задачами она более чем может справится
- есть возможность не промптом, а с помощью макросов управлять и структурировать формат ответа модели. Этот подход назвали "guided generation". Если кратко, то мы описываем энамы и структуры, и говорим, что хотим от модели в таком формате получать ответ и будем его именно так и получать
- появится новый инструмент отладки и тестирования работы с моделью
- самое важное и крутое на мой взгляд: "Tool calling": мы можем "зарегистрировать" функции приложения и сказать модели, что она может к ним обращаться и получать из них информации. Это крутое новшество, которое тянет на отдельный пост, который мы позже принесем
Отдельным пунктом хочу еще выделить, что наконец-то Xcode получит интеграцию с chatgpt и другими llm, в том числе и локально запущенными 🔥
Если хотите глубже погрузиться в архитектуру, узнать больше про пост/пре-трейн и оптимизации моделей, на каких данных и как обучалась, то вам точно нужно зайти сюда. Еще завезли отдельный HIG, посвященный генеративным AI.
#wwdc2025
WWDC прошел и, как обычно, показали много нового и интересного (нет, особенно ужасен новый дизайн Liquid Glass). Для меня самое интересное – это новые AI инструменты и возможности и тут на самом деле было много интересного.
Apple показали фрейморк Foundation Models для работы с llm on-device в приложениях. Из основного:
- полностью нативная реализация и интеграция со swift'ом. Сама модель адаптирована под работу на Apple процессорах
- модель: 3B квантизованная до 2х бит: создать полноценного чат бота с ней не выйдет, но с задачами суммаризации, генерацией / понимаем текста и другими несложными llm-based задачами она более чем может справится
- есть возможность не промптом, а с помощью макросов управлять и структурировать формат ответа модели. Этот подход назвали "guided generation". Если кратко, то мы описываем энамы и структуры, и говорим, что хотим от модели в таком формате получать ответ и будем его именно так и получать
- появится новый инструмент отладки и тестирования работы с моделью
- самое важное и крутое на мой взгляд: "Tool calling": мы можем "зарегистрировать" функции приложения и сказать модели, что она может к ним обращаться и получать из них информации. Это крутое новшество, которое тянет на отдельный пост, который мы позже принесем
Отдельным пунктом хочу еще выделить, что наконец-то Xcode получит интеграцию с chatgpt и другими llm, в том числе и локально запущенными 🔥
Если хотите глубже погрузиться в архитектуру, узнать больше про пост/пре-трейн и оптимизации моделей, на каких данных и как обучалась, то вам точно нужно зайти сюда. Еще завезли отдельный HIG, посвященный генеративным AI.
#wwdc2025
👍10
Code-along: Bring on-device AI to your app using the Foundation Models framework
😮 Продолжаем погружаться в нововведения AI от Apple.
В данном видео разбирают работу с новыми инструментами на примере разработки приложения, помогающего спланировать путешествия.
Из ключевых моментов:
➡️ Написание хорошего промпта играет ключевую роль в достижении хороших результатов. Для упрощения процесса мы можем воспользоваться макросом
Есть две сущности -
Еще в помощь🤫
➡️ Для отладки работы приложения, использующего Foundation Models подвезли новый инструмент. Он так и называется
Здесь будет видно и количество времени, потраченное на загрузку ассетов, обозначен трек инференса, отдельно будут вызовы тулов. Выглядит круто. После профилирования можно сразу заняться оптимизацией - например: делать загрузку модели еще до того, как пользователь отправит свой запрос.
#wwdc2025
В данном видео разбирают работу с новыми инструментами на примере разработки приложения, помогающего спланировать путешествия.
Из ключевых моментов:
#Playground
в любом файле и там экспериментировать с получаемыми результатами - ответ будет сразу на канвасе. Есть две сущности -
Prompt
и Instructions
. Вторая - это что-то вроде системного промпта, недоступного пользователю. Очень полезная штука для предварительной «настройки» модели перед ответом на запросы.Еще в помощь
#Generable
и #Guide
, но про них нужен отдельный пост Foundation Models Instrument
Здесь будет видно и количество времени, потраченное на загрузку ассетов, обозначен трек инференса, отдельно будут вызовы тулов. Выглядит круто. После профилирования можно сразу заняться оптимизацией - например: делать загрузку модели еще до того, как пользователь отправит свой запрос.
#wwdc2025
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6