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

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

По всем вопросам обращаться к @itereznikov
Download Telegram
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
Assembler for Swift developers

Статья про ассемблер для разработчиков на Swift. Вы спросите: зачем

💡 В целом сейчас вы не будете это применять (с вероятностью 98%). Однако понимание самого процесса может оказаться весьма полезным для последующей работы, например, для разбора багов перформанса с не очень читаемым стектрейсом.

1️⃣ Это первая из трёх статей, посвящённых разбору процесса взаимодействия высокоуровневых языков с ассемблером.

👀 В этой части вы разберёте 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
👍52
Streaming changes with Observations

Вы до сих пор используете 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. А в статье автор пытается разобраться со всем этим - в конце даже отличная таблица сравнение.

Вот несколько моментов:

➡️ 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 приносит долгожданное улучшение — Default Actor Isolation, которое меняет подход к конкурентности в Swift. Теперь по умолчанию весь код таргета изолируется на @MainActor, если явно не указано иное. Это снижает количество boilerplate-кода с аннотациями  @MainActor  и  Sendable , упрощая жизнь разработчикам в UI-ориентированных проектах.

Основные идеи и эффекты нового механизма:

➡️ До Swift 6.2 неаннотированный код считался nonisolated, что приводило к множеству предупреждений и ошибок при строгой проверке конкурентности, особенно когда код на самом деле всегда выполнялся на главном потоке.

➡️ Default Actor Isolation меняет это поведение: теперь такой код автоматически считается изолированным на @MainActor.

➡️ В Xcode 26 новые проекты получают эту настройку по умолчанию, а для старых нужно включать ее вручную в настройках компилятора или в Swift Package Manager через defaultIsolation(MainActor.self) 

➡️ nonisolated  сохраняется как способ явного выхода из изоляции, но меняет семантику — асинхронные nonisolated функции уже не “сбрасывают” изоляцию, а наследуют ее от вызывающего контекста.

➡️ Важно аккуратно использовать  nonisolated  и  @concurrent , особенно в сложных многопоточных сценариях.

Новый подход снижает шум ошибок при миграции на Swift 6 и стимулирует более корректное использование модульного дизайна и конкурентного программирования.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42
What's New in UIKit

Принес вам супер лонг рид про нововведение в UIKit в 26 iOS. 64 минуты на чтение - самое то на выходных 🍷

Вот основные моменты и темы, освещённые в статье:

➡️ Обновления UIAction и UIApplicationDelegate: добавлены новые идентификаторы действий и происходит постепенный отход от  UIApplicationDelegate  в пользу более современных  UISceneDelegate  и  UIWindowSceneDelegate 

➡️ Новые визуальные эффекты и компоненты: введён новый класс  UIGlassEffect  с эффектами Liquid Glass, новые API для сглаживания углов в виде  UICornerConfiguration  и  UICornerRadius . Также есть новые опции для кнопок (UIButton.Configuration и элементов навигационной панели UIBarButtonItem, включая новые стили, бейджи иконок и поведение.

➡️ Поддержка HDR-цветов: в  UIColor  и связанных компонентах появляются конструкторы и свойства для работы с HDR, а в UIColorPickerViewController  добавлен HDR-лайтбокс.

➡️ Расширена система меню с новыми методами для тонкой настройки главного меню iPadOS и контекстных меню, а также поддержкой фокусного выбора меню.

➡️ новые свойства для  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
Inspect & optimize Image Decoding timing in iOS

Декодирование изображений в iOS происходит в основном потоке во время фазы коммита Core Animation, что может вызывать зависания приложения при работе с большими изображениями.

⚙️ Используйте методы UIKit, такие как prepareForDisplay и prepareThumbnail, для предварительной обработки изображений в фоновом режиме, чтобы избежать задержек в основном потоке.

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

⚠️ Использование API UIImageReader в iOS 17 может привести к утечкам памяти, которые были исправлены в iOS 18.

Getting HDR UIImage in iOS 17 and display it in a UIImageView will result in major memory leak internally. Apple have fixed this issue on iOS 18
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32
High Level Anatomy of a Camera Capturing Session

Камера или микрофон служат источником для захвата видео, фото или аудио, включая заднюю и фронтальную камеры.

ℹ️ Выход может быть в виде фото или видео, которые сохраняются на диске или обрабатываются для распознавания лиц и применения фильтров.

➡️ AVCaptureSession является центральным контроллером, который управляет входами, выходами и предварительными слоями для захвата медиа.

Метод capturePhoto асинхронный, что означает, что захват фото занимает время из-за фокусировки и экспозиции.

➡️ AVCapturePhoto - это необработанный вывод, PHAsset - ссылка на изображение в библиотеке, CGImage - это битовая карта, а Image в SwiftUI - визуальное представление.
Please open Telegram to view this post
VIEW IN TELEGRAM