Schedule a countdown timer with AlarmKit
Не стал делать обзор
❓ Он позволяет планировать одноразовые будильники, повторяющиеся будильники и таймеры обратного отсчета, которые работают даже в беззвучном режиме.
⚠️ Перед использованием
⌛ Для настройки таймера необходимо создать объект
🔴 Для отображения текущего обратного отсчета во время работы таймера необходимо настроить
🖥
Не стал делать обзор
AlarmKit
из видео сессии, но сразу принес статью с кучей примеров.AlarmKit
необходимо запросить у пользователя разрешение, добавив ключ NSAlarmKitUsageDescription
в Info.plist
и проверив статус авторизации с помощью API AlarmManager
.AlarmPresentation.Alert
с заголовком и кнопкой остановки, а затем использовать AlarmAttributes
для определения его атрибутов перед вызовом метода schedule() AlarmManager
.Live Activity
, добавив Widget Extension
и используя ActivityConfiguration
для отображения состояния таймера на экране блокировки и в Dynamic Island
.AlarmKit
предоставляет асинхронную последовательность для получения всех активных будильников, что позволяет отображать их в приложении и управлять ими, включая возможность отмены.struct TimerButton: View {
private let manager = AlarmManager.shared
var body: some View {
Button("Start a timer", systemImage: "timer") {
Task {
if await checkForAuthorization() {
await scheduleTimer()
} else {
// Handle unauthorized status
}
}
}
}
private func scheduleTimer() async {
let alert = AlarmPresentation.Alert(
title: "Ready!",
stopButton: AlarmButton(
text: "Done",
textColor: .pink,
systemImageName: "checkmark"
)
)
}
...
}
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
Swift concurrency. Executors, Actors и их связь с потоками
🖥
💡 Существуют различные типы
➡️ Разработчики могут создавать свои собственные
➡️
➡️ Используя функцию
Swift Concurrency
включает в себя такие ключевые компоненты, как Task
, Job
и Executor
, которые обеспечивают асинхронное выполнение кода и управление потоками.Executors
: Global concurrent executor
, Serial executors
и Main Actor executor
, каждый из которых выполняет задачи по-разному, обеспечивая гибкость в управлении потоками.Executors
, используя протоколы TaskExecutor
и SerialExecutor
, что позволяет им контролировать выполнение задач в своих приложениях.Actors
в Swift
обеспечивают потокобезопасность, выполняя свои методы последовательно, что предотвращает гонки данных и обеспечивает целостность данных.withUnsafeCurrentTask
, разработчики могут определить, какой Executor
используется в данный момент для выполнения асинхронной функции.
@available(iOS 18.0, *)
final class CustomExecutor: TaskExecutor {
func enqueue(_ job: consuming ExecutorJob) {
job.runSynchronously(on: asUnownedTaskExecutor())
}
func asUnownedTaskExecutor() -> UnownedTaskExecutor {
UnownedTaskExecutor(ordinary: self)
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤2
Ternary operator in Swift explained
Вдруг кто-то не знает про тернарную операцию🫠
❓ Тернарный оператор в Swift позволяет записывать условные выражения в компактной форме, заменяя многословные конструкции if-else на одну строку.
⚙️ Стандартный синтаксис тернарного оператора выглядит как <условие> ? <если истинно> : <если ложно>, например,
➡️ Тернарные выражения полезны для простых проверок, но их следует избегать при сложных или вложенных условиях, чтобы сохранить читаемость кода.
➡️ Тернарные операторы часто используются в модификаторах представлений SwiftUI для условного применения стилей, что делает код более лаконичным.
Вдруг кто-то не знает про тернарную операцию
username.isEmpty ? .gray : .red
.let buttonColor: Color = if username.isEmpty {
.gray
} else {
.red
}
Превращается в
let buttonColor: Color = username.isEmpty ? .gray : .red
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2🤯1
Supporting Universal Links on iOS
🔴 Хороший гайд по работе с универсальными ссылками. Они позволяют пользователям открывать контент вашего приложения через прямые ссылки, обеспечивая более гибкий доступ и возможность делиться контентом.
➡️ Для поддержки универсальных ссылок необходимо иметь сервер, который возвращает корректный JSON-ответ с информацией о приложении и разрешенных путях для ссылок.
➡️ Добавьте
⚙️ Тестируйте универсальные ссылки, открывая их на устройстве; иногда требуется переустановка приложения для корректной работы.
❓ Если пользователь отказывается открывать приложение, предоставьте ему возможность увидеть контент на веб-странице или предложите скачать приложение.
capability
Associated Domains
в проект, указав домен с префиксом applinks:
, чтобы iOS мог проверить права вашего приложения на обработку ссылок.Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Power of Swift Macros
Макросы в Swift достаточно удобная штука, если их правильно применять🙂 Например, они позволяют автоматизировать создание представлений SwiftUI для UIKit, упрощая процесс написания повторяющегося кода.
➡️ Для создания макроса необходимо инициализировать новый Swift пакет с помощью команды ➡️ Основной код макроса включает в себя извлечение метаданных из объявления класса и создание структуры SwiftUI, которая реализует протокол
➡️ Тестирование макроса включает проверку различных случаев, таких как наличие модификаторов и правильность обработки классов, не являющихся представлениями UIKit.
Макросы в Swift достаточно удобная штука, если их правильно применять
swift package init --type macro --name RepresentableMacros
UIViewRepresentable
.import SwiftCompilerPlugin
import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros
public enum ViewRepresentableError: CustomStringConvertible, Error {
case onlyApplicableToView
public var description: String {
switch self {
case .onlyApplicableToView:
"@ViewRepresentable is only applicable to UIKit View."
}
}
}
public struct ViewRepresentable: PeerMacro {
public static func expansion(
of node: AttributeSyntax,
providingPeersOf declaration: some DeclSyntaxProtocol,
in context: some MacroExpansionContext
) throws -> [DeclSyntax] {
// here will be our magic code
return []
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡4
State of in-app subscriptions 2025
Раньше меня очень вдохновляла возможность создавать свои личные приложения и зарабатывать на них. Я не могу назвать себя трушным и успешным инди разработчиком, который достиг невероятных высот, но веху $1k MRR я пробил.
Одна из самых сложных задач при создании продукта: монетизация, если вы не планируете играть в альтруизм. Ребята, которые делают крутой сервис – Adapty, берущий на себя почти все сложности с монетизацией, выпустили крутой отчет, который закрывает кучу вопросов:
⁃ какую длительность подписки выбрать
⁃ нужен ли триал и что он дает
⁃ на какие страны целиться
⁃ и как сделать лучший пейволл
P.S. Сейчас крутое время, чтобы попробовать создать свой пет-продукт: AI тулы и инструменты, как Adapty, сильно упрощают этот путь. Но конкуренция, конечно же, будет жесткая.
Раньше меня очень вдохновляла возможность создавать свои личные приложения и зарабатывать на них. Я не могу назвать себя трушным и успешным инди разработчиком, который достиг невероятных высот, но веху $1k MRR я пробил.
Одна из самых сложных задач при создании продукта: монетизация, если вы не планируете играть в альтруизм. Ребята, которые делают крутой сервис – Adapty, берущий на себя почти все сложности с монетизацией, выпустили крутой отчет, который закрывает кучу вопросов:
⁃ какую длительность подписки выбрать
⁃ нужен ли триал и что он дает
⁃ на какие страны целиться
⁃ и как сделать лучший пейволл
P.S. Сейчас крутое время, чтобы попробовать создать свой пет-продукт: AI тулы и инструменты, как Adapty, сильно упрощают этот путь. Но конкуренция, конечно же, будет жесткая.
👍8🔥2🙏2❤1
The Anatomy of a LiquidGlass Button in iOS 26
😱 Кнопка
⚙️ Для создания круглой кнопки необходимо обрезать форму кнопки, чтобы эффект стекла правильно отображался при нажатии.
❓ Рекомендуется использовать стиль
⚠️ При изменении цвета кнопки в светлом режиме возникают проблемы, где кнопка не отображает выбранный цвет, оставаясь прежней.
LiquidGlass
в iOS 26
имеет стильный эффект стекла, который можно настроить с помощью модификаторов .glass
и .glassProminent
. borderProminent
с эффектом стекла для лучшего отображения в темном режиме, хотя это все еще может быть немного багованным.Please open Telegram to view this post
VIEW IN TELEGRAM
👎3👍2
Using defer in Swift to manage state cleanup
Раз новое не заходит, вспомним старое🥲
⚡️ В
💡 Использование
❓
➡️ Пример использования defer включает управление индикатором загрузки, который показывается во время выполнения асинхронной операции и скрывается по завершении, что предотвращает пропуск очистки состояния:
Раз новое не заходит, вспомним старое
Swift
оператор defer
позволяет гарантировать выполнение кода очистки при выходе из текущей области видимости, независимо от того, завершилась ли функция успешно или с ошибкой.defer
уменьшает вероятность ошибок в коде, особенно в больших функциях, где могут быть добавлены новые возвраты или отмены задач.Defer
гарантирует выполнение кода очистки в различных сценариях: нормальное завершение функции, выброс ошибки, ранний возврат или отмена задачи во время ожидания.func fetch() async {
isLoading = true
defer { isLoading = false }
do {
articles = try await service.fetchArticles()
} catch {
self.error = error.localizedDescription
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1
Memory Efficiency in iOS: Reducing footprint and beyond
🧠 Работа с памятью в приложениях - сложная тема. Правильное управление памятью в мобильных приложениях — это то, что помогает им не зависать и не съедать весь телефон. Если об этом не думать, приложение может тормозить или вовсе вылетать.
❓ Существует два основных подхода к управлению памятью: реактивный, когда проблемы решаются по мере их возникновения, и проактивный, который включает в себя заранее продуманные меры по снижению потребления памяти.
💡 Для снижения потребления памяти важно загружать изображения, соответствующие размеру отображения, и использовать такие инструменты, как
✔️ Правильное использование кэширования, например, с помощью
📊 Утечки памяти могут привести к тому, что объекты остаются в памяти, даже когда они больше не нужны. Используйте инструменты, такие как
⚠️ Для приложений с высокими требованиями к памяти можно запросить расширение виртуального адресного пространства с помощью специальных прав, что может улучшить производительность на поддерживаемых устройствах.
Image I/O
для создания миниатюр и асинхронной загрузки изображений.NSCache
, может значительно улучшить производительность, но важно следить за жизненным циклом кэша и избегать сильных ссылок на большие объекты.Memory Graph Debugger
, для выявления и устранения таких проблем.Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Caching in Swift
✏️ Давно хотел написать про использование кеша. Почему-то его благополучно забывают, когда нужно временное хранилище, а ведь это отличный вариант.
❓ NSCache автоматически управляет памятью, удаляя объекты при нехватке ресурсов, но требует обертки для работы с типами, не основанными на NSObject.
➡️ Создание обертки вокруг NSCache позволяет использовать любые типы ключей и значений, включая структуры, что делает API более гибким.
⚠️ Важно добавлять условия для недействительных кэшированных данных, например, устанавливать срок действия для записей, чтобы избежать отображения устаревшей информации.
⚙️ Кэширование на диске позволяет сохранять данные между запусками приложения, что полезно для доступа к загруженным данным в оффлайн-режиме.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
The Swift Method Dispatch Deep Dive
Если у вас были споры с коллегами относительно использования final для применения другого типа диспатчеризации у класса - дайте им эту статью🧠
🔴 В Swift существуют два основных типа диспетчеризации: статическая (быстрая, но менее гибкая) и динамическая (медленная, но более гибкая), каждая из которых имеет свои подтипы.
❓ Динамическая диспетчеризация может негативно сказаться на производительности из-за потери возможности оптимизации и увеличения вероятности кэш-промахов.
❗️ Понимание того, когда компилятор может определить адрес функции во время компиляции, помогает разработчикам предсказать, как будет происходить диспетчеризация в их коде.
Если у вас были споры с коллегами относительно использования final для применения другого типа диспатчеризации у класса - дайте им эту статью
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
Рисуем чайник в Metal
🤘 Если вы давно мечтали погрузиться в метал - эта статья для вас. Тут вы будете рисовать чайник - почти как
✏️ Для примера используется модель чайника в формате
ℹ️ Работайте с четырьмя системами координат:
⚙️ Создайте экземпляры
🟢 Разработаете вершинный и фрагментный шейдеры, которые обрабатывают данные о вершинах и вычисляют цвет фрагментов на основе нормалей.
👀 Включите
hello world,
только в мире графики..obj
, загружаемая с помощью фреймворка Model I/O
, который создает представление модели и необходимые буферы.Local space
, World space
, View space
и Clip space
, используя матрицы трансформации для перемещения модели.MTLDevice
, MTLCommandQueue
и MTLCommandBuffer
, а также настраиваете MTLRenderPipelineDescriptor
для указания шейдеров и форматов буферов.depth testing
для улучшения реалистичности изображения, позволяя скрывать фрагменты, которые не видны из-за других объектов.Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤🔥3
Uncertain⟨T⟩
❓ Статья обсуждает важность учета неопределенности в программировании, особенно в контексте работы с GPS-данными и вероятностным программированием.
➡️ Предложена система типов
🖥 Код на Swift демонстрирует, как использовать
✏️ Статья объясняет, как метод Монте-Карло может быть использован для оценки вероятностей, например, в азартных играх, позволяя моделировать результаты с помощью случайных выборок.
💡 Рекомендуется поэтапно внедрять неопределенные вычисления в существующий код, начиная с тех функций, где ошибки GPS вызывают наибольшее количество жалоб от пользователей.
Uncertain<T>
, которая позволяет моделировать неопределенные данные, используя вероятностные распределения, что делает код более умным и точным.Uncertain<T>
для работы с GPS-данными, вычислениями скорости и сопротивления воздуха, учитывая неопределенности.Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Assembler for Swift developers
Статья про ассемблер для разработчиков на Swift. Вы спросите: зачем❓
💡 В целом сейчас вы не будете это применять (с вероятностью 98%). Однако понимание самого процесса может оказаться весьма полезным для последующей работы, например, для разбора багов перформанса с не очень читаемым стектрейсом.
1️⃣ Это первая из трёх статей, посвящённых разбору процесса взаимодействия высокоуровневых языков с ассемблером.
👀 В этой части вы разберёте
Статья про ассемблер для разработчиков на Swift. Вы спросите: зачем
Hello, Assembly!
под macOS
на C
, узнаете про используемые регистры на Apple Silicon (Arm64)
и посмотрите на системные вызовы.Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
How to use the @available attribute in Swift
⚠️ Атрибут
✏️ Первый аргумент указывает платформу, а остальные могут включать
⚙️ Для выполнения кода на старых версиях можно использовать проверку
ℹ️ Если используется только аргумент
@available
позволяет определять доступность функций и типов на конкретных платформах или версиях Swift, что полезно при устаревании API или изменении методов.unavailable
, introduced, deprecated, obsoleted, message
и renamed
для управления доступностью кода.if #available
, чтобы условно выполнять код в зависимости от версии платформы.introduced
, можно применять сокращенный синтаксис, что упрощает запись атрибутов доступности.if #available(iOS 17.0, *) {
// Content is available here
} else {
// Fallback to some other code
}
@available(swift 5.10)
@available(iOS 17.0)
struct Content {
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2
Streaming changes with Observations
Вы до сих пор используете Combine? Тогда мы идем к вам 🫵
Ну а если без шуток - речь про фреймворк Observation, который, по сути, заменяет Combine.
👀 Тип
🔗 Этот тип группирует обновления, что позволяет избежать избыточных эмиссий при изменении нескольких свойств одновременно.
⚙️ Автор представляет расширение для протокола
Вы до сих пор используете Combine? Тогда мы идем к вам 🫵
Ну а если без шуток - речь про фреймворк Observation, который, по сути, заменяет Combine.
Observations
соответствует протоколу AsyncSequence
, что позволяет использовать его в асинхронных циклах for-await
, упрощая работу с изменениями состояния.Observable
, позволяющее легко создавать асинхронные последовательности для определенных ключевых путей.extension Observable {
func stream<Value: Sendable>(
of keyPath: KeyPath<Self, Value>
) -> any AsyncSequence<Value, Never> {
Observations {
self[keyPath: keyPath]
}
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Swift 6: Sendable, @unchecked Sendable, @Sendable, sending and nonsending
Прочитав заголовок, кто-то может задаться вопросом: wtf?😐
Но это реалии Swift 6. А в статье автор пытается разобраться со всем этим - в конце даже отличная таблица сравнение.
Вот несколько моментов:
➡️
➡️
➡️
➡️
➡️
Прочитав заголовок, кто-то может задаться вопросом: wtf?
Но это реалии Swift 6. А в статье автор пытается разобраться со всем этим - в конце даже отличная таблица сравнение.
Вот несколько моментов:
Sendable
— это протокол, который позволяет компилятору проверять, может ли тип безопасно передаваться между изоляционными доменами, с автоматическим выводом соответствия для простых типов. @unchecked Sendable -
Используется для типов, безопасность которых была обеспечена другими механизмами, позволяя разработчикам обойти проверки компилятора, но требует осторожности, чтобы не злоупотреблять этой возможностью.@Sendable -
для замыканий указывает, что замыкание может безопасно передаваться между изоляционными доменами, с проверкой безопасности на этапе компиляции.sending -
позволяет передавать объекты без проверки на Sendable
, но гарантирует, что переданный объект не будет использоваться повторно после передачи.nonsending
- используется с nonisolated
для указания, что асинхронный метод должен наследовать изоляцию вызывающего контекста, а не выходить за его пределы.Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Default Actor Isolation: New Problems from Good Intentions
🆕 Swift 6.2 приносит долгожданное улучшение —
Основные идеи и эффекты нового механизма:
➡️ До Swift 6.2 неаннотированный код считался nonisolated, что приводило к множеству предупреждений и ошибок при строгой проверке конкурентности, особенно когда код на самом деле всегда выполнялся на главном потоке.
➡️
➡️ В Xcode 26 новые проекты получают эту настройку по умолчанию, а для старых нужно включать ее вручную в настройках компилятора или в Swift Package Manager через
➡️
➡️ Важно аккуратно использовать nonisolated и
❓ Новый подход снижает шум ошибок при миграции на Swift 6 и стимулирует более корректное использование модульного дизайна и конкурентного программирования.
Default Actor Isolation
, которое меняет подход к конкурентности в Swift. Теперь по умолчанию весь код таргета изолируется на @MainActor
, если явно не указано иное. Это снижает количество boilerplate-кода с аннотациями @MainActor
и Sendable
, упрощая жизнь разработчикам в UI-ориентированных проектах.Основные идеи и эффекты нового механизма:
Default Actor Isolation
меняет это поведение: теперь такой код автоматически считается изолированным на @MainActor
.defaultIsolation(MainActor.self)
nonisolated
сохраняется как способ явного выхода из изоляции, но меняет семантику — асинхронные nonisolated
функции уже не “сбрасывают” изоляцию, а наследуют ее от вызывающего контекста. @concurrent
, особенно в сложных многопоточных сценариях.Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤2
What's New in UIKit
Принес вам супер лонг рид про нововведение в UIKit в 26 iOS. 64 минуты на чтение - самое то на выходных🍷
Вот основные моменты и темы, освещённые в статье:
➡️ Обновления
➡️ Новые визуальные эффекты и компоненты: введён новый класс
➡️ Поддержка HDR-цветов: в
➡️ Расширена система меню с новыми методами для тонкой настройки главного меню iPadOS и контекстных меню, а также поддержкой фокусного выбора меню.
➡️ новые свойства для
➡️ новый класс
Принес вам супер лонг рид про нововведение в UIKit в 26 iOS. 64 минуты на чтение - самое то на выходных
Вот основные моменты и темы, освещённые в статье:
UIAction
и UIApplicationDelegate
: добавлены новые идентификаторы действий и происходит постепенный отход от UIApplicationDelegate
в пользу более современных UISceneDelegate
и UIWindowSceneDelegate
UIGlassEffect
с эффектами Liquid Glass
, новые API для сглаживания углов в виде UICornerConfiguration
и UICornerRadius
. Также есть новые опции для кнопок (UIButton.Configuration
и элементов навигационной панели UIBarButtonItem
, включая новые стили, бейджи иконок и поведение.UIColor
и связанных компонентах появляются конструкторы и свойства для работы с HDR, а в UIColorPickerViewController
добавлен HDR-лайтбокс.UINavigationItem
позволяют задавать комплексные атрибуты титулов и подзаголовков, улучшена работа жестов для интерактивного закрытия экранов и размещения поисковых панелей.UIScrollEdgeEffect
позволяет контролировать эффекты на краях скроллов, а появилось также взаимодействие UIScrollEdgeElementContainerInteraction
для кастомных элементов.Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Getting access to the user’s calendar
🗓 Для работы с календарем и напоминаниями пользователей используется фреймворк
🔴 Перед доступом к календарю необходимо получить разрешение от пользователя, используя ключи конфиденциальности в настройках проекта:
🖥 Для запроса доступа к событиям и напоминаниям используются методы
⚠️ Текущий статус авторизации можно проверить с помощью метода
➡️ Рекомендуется создать отдельный класс, например
EventKitt
, который предоставляет все необходимые инструменты для создания и получения событий.Privacy - Calendars Full Access Usage Description
и Privacy - Reminders Full Access Usage Description
.requestFullAccessToEvents
и requestFullAccessToReminders
, а также requestWriteOnlyAccessToEvents
для приложений, которые не требуют чтения календаря.authorizationStatus(for:)
, который возвращает значения EKAuthorizationStatus
, такие как fullAccess
, writeOnly
, denied
, notDetermined
и restricted
.CalendarPermissionsViewModel
, для управления статусом доступа к календарю и напоминаниям, а также для обработки запросов на доступ.Please open Telegram to view this post
VIEW IN TELEGRAM
👍4