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

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

По всем вопросам обращаться к @itereznikov
Download Telegram
MIT Professor on Data Abstraction & Object-Oriented Programming

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

Советуем смотреть всем, оно небольшое.
❤‍🔥3
Non-Sendable types are cool too you know

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

Non-Sendable типы могут быть полезны для моделирования изменяемого состояния, совместимого с произвольно изолированными клиентами, и могут иметь полезные асинхронные методы. Иными словами, такие типы можно использовать особо не задумываясь о потокобезопасноти.

Использование параметра isolation(any) в сочетании с новыми функциями Swift 6 позволяет non-Sendable типам участвовать в конкурентности, обеспечивая безопасность и гибкость.
🔥2
iOS App Launch Optimization: How Cityflo Achieved 2.22x Faster Load Times

Запуск приложения кажется незаметным, пока не становится долгим. И чем больше логики тем сложнее это оптимизировать.

В статье автор поделился опытом ускорения запуска приложения с рассмотрением всех моментов, на которые они сделали упор после анализа времени запуска: оптимизацию библиотек, ленивая инициализация, рефакторинг AppDelegate, удаление избыточной логики и оптимизация последовательности вызовов API.
👍32
Streamlining NotificationCenter Usage in Swift

Автор описывает интересный подход использования NotificationCenter у себя в проекте: создание протокола с расширением, содержащим некоторые реализации функций. Это позволяет поддерживать чистоту в коде, а также дает возможность проводить тестирование такой функциональности.
❤‍🔥2
Как вернуть контроль над состоянием данных с RemoteResult

Автор предлагает расширить Result, чтобы сделать его более удобным и преварить его в:


enum RemoteResult<Success, Failure: Error> {
case idle
case loading
case success(Success)
case failure(Failure)
}


Это позволит лучше управлять состоянием данных и реагирововать на состояние загрузки и «простоя». RemoteResult может быть адаптирован для использования в архитектурах программирования, таких как The Composable Architecture, путем внесения простых изменений для совместимости с логикой сравнения состояний.
3👍1😁1
Recursive enums in Swift

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

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


enum FileSystemItem {
case file(name: String)
case folder(name: String, items: [FileSystemItem])
indirect case alias(name: String, to: FileSystemItem)
}
👍5
Subtitle Shenanigans in SwiftUI’s Menu

Компонент Menu из SwiftUI – невероятно сложный API с точки зрения сложности поддерживаемых им взаимодействий. В статье рассматриваются неочевидные способы его настройки и обсуждаются распространенные проблемы, с которыми сталкиваются разработчики при использовании HStack и VStack и предлагаются практические решения для их преодоления.

Статья еще интересна с точки зрения того, как можно разбирать документированные API и находить в них несоответствия, а также искать способы решения.
👍3
viewIsAppearing

Некоторые могли пропустить, но на WWDC 2023 было представлено важное дополнение про жизненный цикл контроллера.

Этот метод вызывается после вызова viewWillAppear и перед вызовом viewWillLayoutSubviews. Отлично подходит для fine-tune'а динамического интерфейса или самой презентации контроллера.
❤‍🔥9
Typed throws in Swift

В Swift 6.0 изменили привычный подход работы с выбрасываемыми ошибками: в прошлых версиях нельзя было указать конкретный тип. Теперь компилятор будет понимать какую именно ошибку мы будем выбрасывать.


enum FooError: Error {
case tooBig
case tooSmall
}

func foo() throws(FooError) -> Int {
let value = Int.random(in: 1...100)

guard value < 60 else {
throw FooError.tooBig
}

guard value > 20 else {
throw FooError.tooSmall
}

return value
}



В месте использования нам теперь не нужно лишнее приведение типов.


func boo() {
do {
let value = try foo()
print(value)
} catch {
switch error {
case .tooBig:
print("Too big...")
case .tooSmall: print("Too small...")
}
}
}
27
Performance Testing для iOS

Для тестирования производительности iOS приложений существуют различные способы, включая использование Xcode Organizer, MetricKit и TestFlight для анализа показателей запуска, отзывчивости интерфейса, потребления памяти и других аспектов.

В статье разобраны различные способы сбора метрик, в том числе использование блока measure для измерения производительности кода, создание signpost'ов, а также запись данных и последующий анализ результатов для определения трендов.
72
Upload iOS App to TestFlight with GitHub Actions and Fastlane Match

Если вы проводите деплой приложения руками и вас это достало, то это статья для вас. Автор рассказывает, как провести настройку деплоя используя fastlane, связке с GitHub Secrets для хранения ключей и GitHub actions для построения полноценного workflow.

Неплохая статья для понимания того, как работает Continuous Deployment.
3🔥2
Marking Swift Properties Available by iOS Version

В текущих версиях Swift мы можем пометить структуры, классы и расширения доступными для определенных версий ОС.


@available(iOS 18.0, *)
struct GetQuoteControlWidget: ControlWidget {
// code
}


Но не можем так поступить со свойствами. В статье предлагается способ сделать это с помощью старого доброго NSObject и вычисляемого свойства, для достижения такого же результата.


private var _customTool: NSObject? = nil
@available(iOS 18.0, *)
private var customToolWrapper: PKToolPickerCustomItem {
if _customTool == nil {
let tool = PKToolPickerCustomItem(configuration: .init(identifier: someID, name: someName))
_customTool = tool
}
return _customTool as! PKToolPickerCustomItem
}
7
SWIFT BUILD TIMES AND MODULE VERIFICATION

После расширения кодовой базы и рефакторинга, автор разбил приложение на множество модулей и стал замечать просадки в сборке проекта. После исследования он обнаружил, что флаг ENABLE_MODULE_VERIFIER был установлен в YES. Сам флаг отвечает за верификацию модулей на этапе сборки. Автор выключил этот флаг для дебаг сборок и уменьшил время с 3,5 минут до 52 секунд.
Но стоит понимать, что этот флаг не панацея и он лишь экономит время сборки, пропуская один из этапов и перед отправкой релизной сборки его все же стоит включить обратно.
5
Benchmark Package

Не так давно был представлен новый пакет Benchmark. Его основная цель – измерение производительности. Количество метрик из коробки большое: 27.
Так же можно добавлять свои метрики.

На выходе будем получать таблицу с измерениями. Но можно сохранять данные и в других форматах.

Выглядит круто и работоспособно.
5
Борьба с утечками памяти: от задачи до победы

Классное видео с мобиуса про борьбу с утечками памяти: тут и про работу с Memory Graph, про который не так много документации и примеры про автоматизацию поиска утечек через UI тесты.
10
Антимат в чате на iOS: как я мешаю пользователям сквернословить

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

Как MVP точно пойдет и не факт, что продуктово имеет смысл делать что-то лучше.
4
Morphology in Swift

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

С iOS 15 Foundation предлагает решение этой проблемы, позволяя автоматически обрабатывать такие ситуации и термины обращения в локализованных строках.


Text("She will receive ^[\(count) games](inflect: true).")


Для более точного управления в Swift можно использовать структуру Morphology, позволяющую выполнять ручное согласование грамматики во время выполнения.
5
Wrapping async-await with a completion handler in Swift

Статья про то, как обернуть async-await кода в completion handler. Вы столкнетесь с таким, например, если используете сторонние библиотеки, которые принимают только хендлеры, а ваша кодовая база на основе Swift Concurrency.


extension Task {
@discardableResult
init<T>(
priority: TaskPriority? = nil,
operation: @escaping () async throws -> T,
queue: DispatchQueue = .main,
completion: @escaping (Result<T, Failure>) -> Void
) where Success == Void, Failure == any Error {
self.init(priority: priority) {
do {
let value = try await operation()
queue.async {
completion(.success(value))
}
} catch {
queue.async {
completion(.failure(error))
}
}
}
}
}
2
The Memory Leak: An Xcode Detective Story

История о том, как инженер пытался отладить простой по описанию баг и как глубоко он зашел. Если очень коротко, то проблема была в неправильном использовании [weak self] в кложуре 🫠

Понимание механизмов работы с памятью помогает избегать таких ситуаций.
4🔥21
Announcing Swift 6

Анонсировали релиз Swift 6 🥳 и нас ждет очень много изменений, вот небольшой список:
- поддержка 128-битных целых чисел
- новая библиотека синхронизации, которая включает примитивы, такие как mutex
- новый подход к выбрасыванию ошибок
- владение некопируемых типов
- расширение интеропа с C++
- новый макрос для отображения информации в LLDB @DebugDescription
- фреймворк для тестирования Swift Testing
🔥10