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

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

По всем вопросам обращаться к @itereznikov
Download Telegram
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
👍4
Certificate Pinning on iOS in Practice

Статья про то, что такое certificate pining и как его настроить.

⚠️ Основная цель реализации certificate pining — защита от атак типа человек посередине, которые могут позволить злоумышленникам перехватывать данные пользователей и тестировать уязвимости API.

🖥 Certificate pining включает в себя проверку цепочки сертификатов, состоящей из корневого, промежуточного и конечного сертификатов, с акцентом на конечный сертификат для обеспечения безопасности соединения.

ℹ️ Можно пиннить как весь сертификат, так и его отпечаток или открытый ключ, что дает гибкость в управлении сертификатами, особенно при их обновлении.

❗️ Обновление сертификатов может быть неудобным, так как требует обновления приложения. Рекомендуется использовать пиннинг открытого ключа или удаленные обновления сертификатов через такие решения, как CloudKit.

⚙️ Для реализации certificate pining в iOS необходимо использовать URLSessionDelegate для обработки аутентификационных вызовов и проверки доверенных сертификатов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Swift Computed Property: Code Examples

Вдруг вы не знаете, что такое вычисляемое свойство - эта статья для вас 🙂

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

Computed properties могут использоваться для создания значений, таких как имя файла, основанное на других свойствах, или для управления доступом к внутренним объектам через публичные интерфейсы.

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

Вычисляемые свойства могут иметь асинхронные геттеры, позволяя использовать await для выполнения операций, таких как валидация данных перед возвратом значения.

struct Content {
enum ContentError: Error {
case emptyFileExtension
}

let name: String
let fileExtension: String

/// A computed property to generate a filename.
/// Throws an error when the file extension is empty.
var filename: String {
get throws(ContentError) {
guard !fileExtension.isEmpty else {
throw .emptyFileExtension
}

return name + "." + fileExtension
}
}
}

/// We now need to use the `try` keyword when accessing:
print(try content.filename) // Prints: "swiftlee-banner.png"
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Overview on Accessibility Nutrition Labels for iOS development

ℹ️ На WWDC25 Apple представила метки доступности, которые отображаются в App Store и информируют пользователей о поддерживаемых функциях доступности приложений.

🖥 Разработчики могут заявить о поддержке таких функций, как VoiceOver, Voice Control, Dynamic Type, Dark Mode, и других, чтобы улучшить доступность своих приложений.

🔈 VoiceOver - это экранный диктор, который помогает пользователям навигировать по приложению без визуального контакта, требуя от разработчиков ручной настройки для улучшения опыта.

🔍 Поддержка Dynamic Type позволяет пользователям увеличивать размер текста на устройствах iOS, что делает текст более читаемым и удобным.

➡️ Поддержка достаточной контрастности помогает пользователям с низким зрением; разработчики могут использовать инструмент Color Contrast Calculator в Xcode для проверки соответствия.

➡️ Субтитры обеспечивают текстовую альтернативу для пользователей с нарушениями слуха, а аудиодескрипции предоставляют устное описание визуального контента для пользователей с нарушениями зрения.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Inside Code Signing: Provisioning Profiles

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

В этом, например, рассказывают, что такое Provisioning Profiles и что за ними скрывается.

🔍 Профили Provisioning связывают пять критериев: кто может подписывать код, какие приложения могут быть подписаны, где и когда они могут работать, и как они могут быть уполномочены.

ℹ️ Профили создаются на сайте Apple Developer и могут быть подписаны криптографически. Для проверки профиля используется инструмент codesign.

🖥 Профиль представляет собой список свойств, включая сертификаты разработчиков, идентификатор приложения, список устройств и дату истечения срока действия.

⚙️ Современные системы используют бинарную форму профиля, хранящуюся в свойстве DER-Encoded-Profile, что является новым источником правды для профилей.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Что придумал Тим Кук кроме нового айфона? Узнаем в компании VK и Coffee&Code.

9 сентября встречаемся в Москве в офисе VK в Авроре. Будем смотреть и обсуждать презентацию, играть в бинго, общаться и чилить с попкорном и чипсиками.

Регистрация — тут. Ждём вас!
4🔥3❤‍🔥1👎1🥰1
Secret Management on iOS

🙅‍♂️ Если по какой-то причине вы храните токены или ключи в исходном коде - у меня для вас плохие новости: так не стоит делать

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

⚠️ Обфускация секретов с помощью генерации кода и шифрования может затруднить их извлечение, но не гарантирует полной безопасности.

Лучший способ защитить секреты — это не хранить их на клиенте. Если это невозможно, следует рассмотреть возможность использования серверного хранения и обфускации для снижения рисков.

ℹ️ Исследования показывают, что тысячи секретов, таких как API-ключи, ежедневно утечка на платформах, таких как GitHub, что подчеркивает важность безопасного управления секретами.

Пусть статья и не новая, но актуальная.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Взлом через картинку в Apple: уроки громкой уязвимости для разработчиков

🚨 Уязвимость PT-2025-34177 (CVE-2025-43300) в системном фреймворке ImageIO позволяет злоумышленникам выполнять произвольный код через вредоносные изображения, что ставит под угрозу миллионы устройств Apple.

‼️ Атака может происходить без взаимодействия пользователя (zero-click), что делает её особенно опасной, так как уязвимость использовалась в реальных атаках на конкретных людей.

🔼 Пользователям рекомендуется обновлять свои устройства до последних версий iOS/Android для уменьшения риска быть атакованным и избегать открытия подозрительных файлов, особенно если они приходят как документы.

Для предотвращения подобных уязвимостей необходимо внедрять процессы безопасной разработки, включая фаззинг и статический анализ кода, а также использовать методы защиты от реверс-инжиниринга.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Debugging Swift Concurrency: “Am I on the Main Actor?”

В Swift 6 важно думать не о потоках, а о акторах, чтобы избежать ошибок с доступом к пользовательскому интерфейсу и тяжелым вычислениям.

⚠️ Используйте MainActor.assertIsolated() для проверки, что код выполняется на главном актере, что помогает выявить ошибки во время разработки.

Можно создавать собственные актеры с помощью @globalActor, что позволяет использовать аналогичные методы проверки изоляции.

➡️ Используйте информацию о очереди в Xcode для понимания контекста выполнения актеров и отладки проблем с многопоточностью.
Please open Telegram to view this post
VIEW IN TELEGRAM
6
Жизненный цикл UIViewController в 2025 году: что изменилось и что устарело

🔍 Методы viewDidUnload и didReceiveMemoryWarning устарели, в то время как новые хуки, такие как viewIsAppearing и viewSafeAreaInsetsDidChange, стали стандартом для работы с UIViewController.

Классический жизненный цикл UIViewController включает методы инициализации, загрузки представления, а также методы для управления отображением и изменениями окружения.

🔗 Для корректного управления дочерними контроллерами необходимо использовать методы addChild и removeFromParent, чтобы обеспечить правильное получение событий жизненного цикла.

➡️ Рекомендуется использовать методы updateViewConstraints и traitCollectionDidChange для адаптации интерфейса к изменениям окружения, таким как смена темы или ориентации устройства.

➡️ Методы для восстановления состояния, такие как encodeRestorableState и decodeRestorableState, остаются актуальными, однако большинство разработчиков предпочитают использовать UserDefaults или CoreData для сохранения данных.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍6
Debug crashes in iOS using MetricKit

⚠️ MetricKit — это система для сбора и анализа отчетов о сбоях на уровне системы, которая была введена в iOS 13, позволяя выявлять сбои, которые традиционные инструменты не могут зафиксировать.

Для начала работы с MetricKit необходимо импортировать его в AppDelegate и подписаться на протокол MXMetricManagerSubscriber, чтобы получать отчеты о сбоях.

ℹ️ Отчеты о сбоях обрабатываются с помощью метода handleCrashDiagnostics, который позволяет логировать краткие сводки, анализировать стек вызовов и архивировать информацию о сбоях.

🔍 Для тестирования реализации MetricKit можно симулировать сбои, такие как выход за пределы массива или принудительное развертывание nil, и проверить, как система реагирует на эти сбои.

class AppDelegate: UIResponder, UIApplicationDelegate, MXMetricManagerSubscriber {

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Register as a subscriber to receive metrics and diagnostics
MXMetricManager.shared.add(self)
return true
}

// Implement the required delegate method for diagnostics
func didReceive(_ payloads: [MXDiagnosticPayload]) {
// Process crash reports
for payload in payloads {
if let crashDiagnostics = payload.crashDiagnostics {
handleCrashDiagnostics(crashDiagnostics)
}
}
}

func applicationWillTerminate(_ application: UIApplication) {
// Unsubscribe when the app terminates
MXMetricManager.shared.remove(self)
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
ARC в Swift

🎉 Всех с прошедшим Днем программиста! И чтобы не забывать основы - принес статью про механизм подсчета ссылок.

ARC (Automatic Reference Counting) - это метод управления памятью в Swift, который автоматически отслеживает количество сильных ссылок на объекты и освобождает их, когда счётчик достигает нуля.

⚠️ Циклы сильных ссылок (retain cycles) могут возникать, когда два объекта ссылаются друг на друга, что мешает ARC освободить память. Это может привести к утечкам памяти.

🔗 Weak ссылки не учитываются ARC при подсчёте ссылок, что помогает избежать retain cycles, в то время как unowned ссылки никогда не становятся nil, но могут крашнуть приложение при обращении к уничтоженному объекту.

⚙️ ARC работает на уровне SIL (Swift Intermediate Language), где компилятор автоматически добавляет инструкции подсчёта ссылок, что делает код более чистым и безопасным.

✔️ Автоматический подсчет ссылок упрощает управление памятью, избавляя разработчиков от необходимости вручную управлять ссылками, что делает код более лаконичным и понятным.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥62👍2
Swift 6.2 Released

⚡️ Swift 6.2 выпущена 15 сентября. Кратко, что нового.

Упрощенное написание безопасного параллельного кода с помощью новых атрибутов, таких как @concurrent, и делает код однопоточным по умолчанию.

🔒 В новой версии добавлены типы InlineArray и Span, которые обеспечивают безопасный доступ к памяти и высокую производительность без дополнительных затрат.

🔥 Расширение Swift для VS Code теперь официально подтверждено и включает функции, такие как фоновая индексация и встроенная отладка с LLDB.

Swift 6.2 теперь поддерживает WebAssembly, позволяя создавать приложения для браузеров и других сред выполнения.

⚙️ Библиотеки Swift 6.2 включают новый пакет Subprocess для управления внешними процессами и улучшенный API для NotificationCenter.
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍21🔥1
Не могу не поделиться важной и крутой инфой: мой друг выпустил 10 часовой бесплатный курс!!! про iOS разработку для начинающих 🔥

Если вы начали изучать Swift – обязательно к просмотру. И не забывайте делиться с теми, кто тож хочет начать этот увлекательный путь.

https://www.youtube.com/watch?v=SUKocLwjA5k
🔥8👍52
Как Swift Runtime влияет на производительность iOS-приложений

⚡️ Тут наши ребята рассказывают про производительность - супер объемный и полезный обзор. Вот лишь несколько моментов.

⚙️ Swift Runtime играет ключевую роль в производительности iOS-приложений, особенно в управлении памятью и проверке соответствия типов, что может значительно замедлить работу приложения.

‼️ Метод swift_conformsToProtocolMaybeInstantiateSuperclasses является узким местом производительности, так как он может занимать от 1 до 3 мс на каждом вызове, особенно при использовании операторов as? и as! или методов String(describing:) и String(reflecting:).

⚠️ Рекомендуется избегать использования String(describing:) и операторов as? и as!, а также минимизировать использование type-generic-constraint-ов для повышения производительности приложения.

🤫 Использование type-generic-constraint-ов может значительно замедлить приложение, так как каждый вызов метода swift_conformsToProtocolMaybeInstantiateSuperclasses требует проверки
соответствия для каждого протокола.

💯 Рекомендую к прочтению.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥2
Swift Default Value in String Interpolations

🔥 Swift 6.2 улучшает интерполяцию строк с опциональными значениями, позволяя использовать параметр значения по умолчанию.

При интерполяции строк с опционалами компилятор выдает предупреждение, если не указано значение по умолчанию.

🤫 Теперь можно использовать новый параметр по умолчанию в строке, чтобы она не зависела от типа опционального значения. Однако, он не будет работать с локализацией: LocalizedStringKey не поддерживает такой формат.

// The count is not set
Text("The count is \(count, default: "not set")")
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Строки в Swift

Строки в Swift представляют собой контейнеры для символов и являются типами значений, что отличает их от многих других языков программирования.

➡️ Для доступа к символам в строках Swift используется специальный тип индекса String.Index, а не обычные целые числа, что связано с особенностями представления символов.

🖥 Строки могут быть представлены в различных кодировках, таких как unicodeScalars, utf16 и utf8, каждая из которых имеет свои особенности и количество кодовых точек. Сами же строки используют оптимизацию Copy-on-Write, что позволяет эффективно управлять памятью и ускорять доступ к данным.

➡️ Строки Swift могут быть конвертированы в NSString и обратно, что позволяет использовать их в проектах, где смешиваются Swift и Objective-C.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Command tools, threads and QoS

Почему супер навороченные новые мак не могут быстро сжать большую папку через tar? 🤕
Крайне интересная статья, которая поможет лучше разбираться в многопоточности на примере реальной задачи архивирования. Вот краткое содержание.

macOS использует различные уровни QoS для распределения потоков по ядрам процессора, что влияет на производительность. QoS варьируется от 9 (background) до 33 (userInteractive).

ℹ️ Однопоточные процессы, такие как tar, значительно медленнее многопоточных альтернатив, которые могут использовать все доступные производительные ядра.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Feature flags in Swift

🚩 Feature flags в Swift позволяют включать и отключать определенные функциональности. В статье автор приводит в пример в зависимости от конфигурации сборки, таких как Debug, TestFlight и App Store.

По умолчанию в Xcode есть две конфигурации: Debug и Release. Рекомендуется создавать дубликаты для App Store и TestFlight для управления функциональностью.

🔥 Создание перечисления Distribution и структуры FeatureFlags позволяет управлять доступом к функциям в зависимости от текущей конфигурации сборки.

ℹ️ Такой механизм следует рассматривать как временный инструмент и удалять флаги, когда функция готова. Рассмотрите возможность удаленной настройки для мгновенного включения или отключения функций. Крайне полезный инструмент.

public struct FeatureFlags: Sendable, Decodable {
public let requirePaywall: Bool
public let requireOnboarding: Bool
public let featureX: Bool

public init(distribution: Distribution) {
switch distribution {
case .debug:
self.requirePaywall = true
self.requireOnboarding = true
self.featureX = true
case .appstore:
self.requirePaywall = true
self.requireOnboarding = true
self.featureX = false
case .testflight:
self.requirePaywall = false
self.requireOnboarding = true
self.featureX = true
}
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
How to unwrap [weak self] in Swift Concurrency Tasks?

🔍 В Swift, использование [weak self] в замыканиях помогает избежать циклов удержания, но не всегда необходимо, особенно для не-escaping замыканий.

Создание неструктурированного Task может привести к утечкам памяти, если [weak self] используется неправильно, так как Task начинает выполняться сразу после его создания.

Task { [weak self] in
guard let self else { return } // это не решает проблему

let data = await loadData()
let models = await processData(data)
}


✔️ Для предотвращения сильного удержания self в Task, рекомендуется проверять наличие self внутри тела цикла или использовать self? для избежания распаковки.

При выполнении длительных задач, таких как загрузка нескольких страниц, перемещение guard let self внутрь цикла позволяет избежать удержания self дольше, чем это необходимо.

Task { [weak self] in
let data = await loadData()
guard self != nil else { return }

guard let models = await self?.processData(data) else {
return
}

// use models
}
Please open Telegram to view this post
VIEW IN TELEGRAM
4👎2🔥1