EasySwift iOS🍏
3.02K subscribers
269 photos
8 videos
395 links
Все самое интересное в мире iOS разработки 🧑🏻‍💻

Предложить статью или новость: @EasySwiftBot

По всем вопросам обращаться к @itereznikov
Download Telegram
What’s new in UIKit

🆕 UIKit теперь поддерживает автоматическое отслеживание Observable объектов, что упрощает синхронизацию пользовательского интерфейса без необходимости вручную вызывать setNeedsLayout.

ℹ️ В iOS 26 представлен новый дизайн с материалом Liquid Glass, который обновляет стандартные компоненты UIKit и улучшает навигационные переходы.

✏️ UIKit теперь позволяет интегрировать сцены SwiftUI с помощью нового протокола UIHostingSceneDelegate, что упрощает совместное использование UIKit и SwiftUI в приложениях.

➡️ UIKit расширяет поддержку HDR, позволяя создавать HDR цвета и использовать их в UIColorPickerViewController, что улучшает визуальные эффекты в приложениях.

➡️ Введен новый метод updateProperties для UIView и UIViewController, который позволяет более эффективно обновлять свойства без лишних проходов по макету.

#wwdc2025
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
Automatic Observation Tracking in UIKit and AppKit: The Feature Apple Forgot to Mention

А вот и обзор изменений для обновления UI.

🔴 В iOS 18 и macOS 15 добавлено автоматическое отслеживание изменений для UIKit и AppKit, позволяющее обновлять интерфейс без ручных вызовов методов, таких как setNeedsDisplay().

👀 Чтобы активировать автоматическое отслеживание, необходимо добавить ключ UIObservationTrackingEnabled в Info.plist для UIKit и NSObservationTrackingEnabled для AppKit.

Автоматическое отслеживание работает в методах, таких как viewWillLayoutSubviews() и layoutSubviews(), что упрощает синхронизацию данных и интерфейса.

☄️ В iOS 26 добавлены новые методы, такие как updateProperties(), которые обеспечивают более эффективное обновление свойств перед layoutSubviews, улучшая производительность.

⚠️ Важно учитывать, что отслеживание происходит только в определенных методах, и необходимо следить за безопасностью потоков и возможными утечками памяти.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Profile and optimize power usage in your app

☄️ Очень крутая сессия про профилирование использования батареи приложением - вся функциональность блекнет на фоне быстро садящегося телефона.

🆕 Используйте Power Profiler в Instruments для выявления и устранения проблем с энергопотреблением в приложениях, что позволяет улучшить время работы от батареи.

📊 При разработке новых функций сравнивайте влияние различных реализаций на энергопотребление, проводя тесты в разных условиях и усредняя результаты.

⚠️ Включите режим разработчика и Performance Trace на устройстве, чтобы собирать данные о потреблении энергии в реальных условиях, что помогает выявить проблемы, которые невозможно воспроизвести в процессе разработки.

⚙️ Используйте инструменты Xcode, такие как Energy Gauges, XCTest и MetricKit, для мониторинга и оптимизации энергопотребления на всех этапах разработки и после выпуска приложения.

#wwdc2025
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32
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
👍42
Ternary operator in Swift explained

Вдруг кто-то не знает про тернарную операцию 🫠

Тернарный оператор в Swift позволяет записывать условные выражения в компактной форме, заменяя многословные конструкции if-else на одну строку.

⚙️ Стандартный синтаксис тернарного оператора выглядит как <условие> ? <если истинно> : <если ложно>, например, username.isEmpty ? .gray : .red.

➡️ Тернарные выражения полезны для простых проверок, но их следует избегать при сложных или вложенных условиях, чтобы сохранить читаемость кода.

➡️ Тернарные операторы часто используются в модификаторах представлений SwiftUI для условного применения стилей, что делает код более лаконичным.

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
👍52🤯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 пакет с помощью команды swift package init --type macro --name RepresentableMacros

➡️ Основной код макроса включает в себя извлечение метаданных из объявления класса и создание структуры SwiftUI, которая реализует протокол UIViewRepresentable.

➡️ Тестирование макроса включает проверку различных случаев, таких как наличие модификаторов и правильность обработки классов, не являющихся представлениями UIKit.

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, сильно упрощают этот путь. Но конкуренция, конечно же, будет жесткая.
👍8🔥2🙏21
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

Раз новое не заходит, вспомним старое 🥲

⚡️ В Swift оператор defer позволяет гарантировать выполнение кода очистки при выходе из текущей области видимости, независимо от того, завершилась ли функция успешно или с ошибкой.

💡 Использование 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
👍41
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 существуют два основных типа диспетчеризации: статическая (быстрая, но менее гибкая) и динамическая (медленная, но более гибкая), каждая из которых имеет свои подтипы.

Динамическая диспетчеризация может негативно сказаться на производительности из-за потери возможности оптимизации и увеличения вероятности кэш-промахов.

❗️ Понимание того, когда компилятор может определить адрес функции во время компиляции, помогает разработчикам предсказать, как будет происходить диспетчеризация в их коде.
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-данными и вероятностным программированием.

➡️ Предложена система типов Uncertain<T>, которая позволяет моделировать неопределенные данные, используя вероятностные распределения, что делает код более умным и точным.

🖥 Код на Swift демонстрирует, как использовать Uncertain<T> для работы с GPS-данными, вычислениями скорости и сопротивления воздуха, учитывая неопределенности.

✏️ Статья объясняет, как метод Монте-Карло может быть использован для оценки вероятностей, например, в азартных играх, позволяя моделировать результаты с помощью случайных выборок.

💡 Рекомендуется поэтапно внедрять неопределенные вычисления в существующий код, начиная с тех функций, где ошибки GPS вызывают наибольшее количество жалоб от пользователей.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4