EasySwift iOS🍏
2.95K subscribers
274 photos
9 videos
444 links
Все самое интересное в мире iOS разработки 🧑🏻‍💻

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

По всем вопросам обращаться к @itereznikov
Download Telegram
GSoC 2025 Showcase: Improved Code completion for Swift

🆕 Если вы вдруг пропустили - проект улучшает отображение документации во время автозаполнения кода в SourceKit-LSP, позволяя видеть полную документацию вместо кратких аннотаций.

🖥 Основная цель проекта - показать полную документацию для элементов автозаполнения и реализовать поддержку запроса помощи по сигнатурам, показывая доступные перегрузки и их документацию.

🔥 Успешно реализовано извлечение полной документации по запросу и значительная часть поддержки помощи по сигнатурам, что улучшает опыт работы в редакторах, таких как VS Code и Neovim.

Признавайтесь, а вы уже пишите под Swift на VS Code или планируете?
Please open Telegram to view this post
VIEW IN TELEGRAM
2
Building Peer-to-Peer Sessions: Sending and Receiving Data with Multipeer Connectivity

Для начала работы с Multipeer Connectivity необходимо создать объект MCPeerID для идентификации устройства и MCSession для установления канала связи между устройствами.

➡️ Данные отправляются с помощью метода send(_:toPeers:with:), где строка сообщения преобразуется в формат Data с кодировкой UTF-8. Обработка ошибок обязательна для успешной передачи.

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

➡️ Метод session(_:didReceive:fromPeer:) используется для обработки полученных данных, которые преобразуются обратно в строку и добавляются в массив полученных сообщений.

Для приглашения другого устройства в сессию используется метод invitePeer(_:using:), который позволяет отправить приглашение на подключение.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Меня снова спросили за Optional

Очередная база 🤩

➡️Опционалы представляют собой перечисление с двумя кейсами: .none и .some(T), что позволяет создавать универсальные контейнеры для различных типов данных.

✔️ Для инициализации опционалов без использования кейсов необходимо подписать их под протоколы ExpressibleByNilLiteral и ExpressibleByIntegerLiteral, что позволяет использовать nil и литералы напрямую.

⚠️ Наиболее популярный способ распаковки опционалов — это оператор nil-coalescing (??), который позволяет подставить значение по умолчанию, если опционал пустой.

ℹ️ Для реализации сравнения опционалов необходимо сначала реализовать протокол Equatable, а затем Comparable, что позволяет использовать операторы равенства и сравнения.

enum MyOptional<T> {
case none
case some(T)
}

extension MyOptional: ExpressibleByIntegerLiteral where T == Int {
init(integerLiteral value: Int) {
self = .some(value)
}
}

extension MyOptional {

static func ?? (optional: MyOptional<T>, defaultValue: @autoclosure () -> T) -> T {
switch optional {
case .none:
return defaultValue()

case let .some(unwrappedValue):
return unwrappedValue
}
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
К какому компоненту отнести тот или иной класс? Мой опыт разделения функциональности между компонентами

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

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

Устойчивость компонента можно оценить с помощью метрики I, которая рассчитывается как Fan-out ÷ (Fan-in + Fan-out), где значение 0 указывает на максимальную устойчивость.

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

✔️ Принципы REP, CCP и CRP помогают определить, как компоненты должны быть связаны, чтобы обеспечить удобство сопровождения и повторного использования, избегая ненужных зависимостей.

На начальных этапах разработки важнее удобство сопровождения, тогда как на более зрелых стадиях акцент смещается на удобство повторного использования компонентов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32
Improving the approachability of data-race safety

🖥 Документ из Swift Evolution описывает видение по повышению удобства Swift 6 concurrency, фокусируясь на устранении ложных ошибок data-race safety в последовательном коде и упрощении миграции. Основные цели — сохранить безопасность памяти, сделать базовый concurrency простым и продвинутое — естественным, с тремя этапами: последовательный код, async без параллелизма, затем parallelism для производительности.

Модель Swift 6 предполагает конкурентность по умолчанию, что приводит к ложным срабатываниям ошибок в коде, который на самом деле является однопоточным.

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

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

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

ℹ️ Хоть документ и не новый, рекомендую с ним ознакомиться - сможете лучше понимать куда в целом движется развитие языка.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Bridging completion handlers to Swift's async/await

🔍 Если хотели провести миграцию с completion handlers на async/await - загляните в статью. Вот пару советов из нее.

✔️ Функция withCheckedContinuation позволяет создать асинхронную функцию, которая обрабатывает результат из API с обработчиком завершения, обеспечивая безопасное возобновление выполнения.

⚠️ Для API, которые могут возвращать ошибки, можно использовать withCheckedThrowingContinuation, что позволяет обрабатывать ошибки с помощью синтаксиса try await.

🛡 withCheckedContinuation и withCheckedThrowingContinuation обеспечивают проверку на наличие множественных вызовов resume, в то время как withUnsafeContinuation и withUnsafeThrowingContinuation не выполняют таких проверок, что делает их менее безопасными.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥4👍21
Навигация на SwiftUI: чего не хватает и как исправить

Извечный вопрос: курица или яйцо как сделать навигацию в SwiftUI? В статье авторы попытались найти на него ответ, с учетом разных и сложных флоу.

⚙️ Для масштабных проектов необходима поддержка различных навигационных компонентов, таких как Bottom Sheet, алерты и диплинки, что требует продуманной архитектуры.

➡️ Использование паттерна Coordinator позволяет разделить логику навигации и отображения, что упрощает поддержку и тестирование приложений.

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

➡️ Реализация динамических шторок в SwiftUI до iOS 16 была сложной, и для этого часто использовались UIKit-библиотеки, что увеличивало сложность навигации.

➡️ Для сложных приложений с диплинками и кастомными алертами рекомендуется использовать UIKit, в то время как для менее сложных задач можно рассмотреть FlowStacks или NavigationStack.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Секреты на клиенте: как снизить вероятность утечки с нуля до почти нуля

🛡 Безопасность - это всегда поиск какого-то баланса. Полностью защититься невозможно, но и вкладывать время и ресурсы в сложные механизмы никто не горит желанием. В статье рассматриваются разные механизмы работы с чувствительными данными.

📱 Apple предлагает несколько встроенных механизмов защиты, таких как Sandboxing, Code Signing и ASLR, которые помогают изолировать приложения и защищать их от атак.

⚠️ Существует несколько категорий угроз, включая подмену (Spoofing), манипуляцию (Tampering) и утечку информации (Information Disclosure), которые могут угрожать безопасности мобильных приложений.

🔴 Злоумышленники используют инструменты статического и динамического анализа, такие как Hopper и Frida, для декомпиляции приложений и извлечения секретов.

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

⚠️ Типичная атака включает джейлбрейк устройства, доступ к .ipa файлу, декодирование бинарного файла и анализ кода для извлечения секретов.

✔️ Рекомендую к прочтению, как минимум для понимания общих принципов.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥4
Core Transferable

Core Transferable предлагает современный подход к доступности типов данных для операций передачи и обмена, включая функции, такие как кнопка Поделиться и перетаскивание. Этот фреймворк доступен на iOS 16.0+, iPadOS 16.0+, macOS 13.0+, tvOS 16.0+, visionOS 1.0+ и watchOS 9.0+

🖥 Протокол Transferable позволяет вашим моделям взаимодействовать с API передачи данных, такими как перетаскивание и копирование, обеспечивая совместимость с системными фреймворками, такими как SwiftUI.

ℹ️ Core Transferable включает несколько встроенных типов представления, таких как CodableRepresentation и FileRepresentation, которые помогают в импорте и экспорте данных.

ℹ️ Пример модели Note демонстрирует, как расширить тип для соответствия протоколу Transferable, включая реализацию различных представлений для передачи данных.

struct Note: Codable {
var text: String
var url: URL


init(url: URL) {
self.url = url
self.text = ""
}
}


extension Note: Transferable {
static var transferRepresentation: some TransferRepresentation {
CodableRepresentation(contentType: .note)
ProxyRepresentation(exporting: \.text)
FileRepresentation(
contentType: .utf8PlainText,
exporting: { note in SentTransferredFile(note.url) },
importing: { received in
let destination = URL(fileURLWithPath: <# ... #>)
try FileManager.default.copyItem(at: received.file, to: destination)
return Self.init(url: destination) })
}
}


extension UTType {
static var note = UTType(exportedAs: "com.example.note")
}
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥2
Monitoring app performance with MetricKit

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

✔️ Для получения данных о производительности необходимо подписаться на MXMetricManager и обрабатывать MXMetricPayload и MXDiagnosticPayload.

ℹ️ Используйте функции logEvent и logCrash для записи событий и сбоев, что позволяет лучше понять причины проблем с приложением.

💡 Данные, собранные MetricKit, можно легко экспортировать в формате JSON для дальнейшего анализа на сервере.

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

final class AppDelegate: NSObject, UIApplicationDelegate, MXMetricManagerSubscriber {
private var analytics: Analytics?

func applicationDidFinishLaunching(_ application: UIApplication) {
MXMetricManager.shared.add(self)
}

nonisolated func didReceive(_ payloads: [MXMetricPayload]) {
for payload in payloads {
if let exitMetrics = payload.applicationExitMetrics?.backgroundExitData {
analytics?.logEvent(
"performance_abnormal_exit",
value: exitMetrics.cumulativeAbnormalExitCount.formatted()
)

analytics?.logEvent(
"performance_cpu_exit",
value: exitMetrics.cumulativeCPUResourceLimitExitCount.formatted()
)

analytics?.logEvent(
"performance_memory_exit",
value: exitMetrics.cumulativeMemoryPressureExitCount.formatted()
)

analytics?.logEvent(
"performance_oom_exit",
value: exitMetrics.cumulativeMemoryResourceLimitExitCount.formatted()
)
}
}
}

nonisolated func didReceive(_ payloads: [MXDiagnosticPayload]) {
for payload in payloads {
if let crashes = payload.crashDiagnostics {
for crash in crashes {
analytics?.logCrash(crash)
}
}
}
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
This media is not supported in your browser
VIEW IN TELEGRAM
Маленький экран — серьёзный вызов!
В VK мобильные разработчики создают опыт, который помещается в карман, но работает на миллионах устройств. Узнайте об их подходах к сложным задачам и ключевых результатах. По ссылке — ролики и даже вакансии!
Маленькая RAM vs новые фичи: как мы повышаем детализацию Карт и сохраняем стабильность

🔥 Интересный кейс, про поиск и решение проблемы на разных девайсах с оперативной памятью.

🔴 В ходе A/B-тестирования Яндекс Карты было выявлено, что увеличение функциональности приводит к росту ошибок out of memory (OOM), особенно на устройствах с 2-3 ГБ оперативной памяти.

🖥 Исследования подтвердили, что устройства с меньшим объемом оперативной памяти чаще сталкиваются с аварийными завершениями, а также выявили критический предел потребления памяти, превышение которого приводит к резкому увеличению ошибок.

ℹ️ Для оптимизации работы приложения было решено разделить устройства на пять классов по объему оперативной памяти, что позволяет адаптировать функциональность в зависимости от возможностей устройства.

🔝 Благодаря новому подходу, 90% пользователей получили доступ к новым 3D-развязкам в навигации, а также к детализированным дорогам с разметкой, что улучшает пользовательский опыт.

🔥 В итоге - расширили набор метрик для отслеживания стабильности приложения, включая количество OOM-ошибок и потребление оперативной памяти, что позволяет принимать более обоснованные решения о функциональности.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1