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

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

По всем вопросам обращаться к @itereznikov
Download Telegram
Calculating the semantic distance between words with the Natural Language framework

Natural Language framework позволяет компьютерам понимать и взаимодействовать с человеческим языком, обрабатывать и анализировать текстовые данные, извлекать значимую информацию и понимать отношения между словами и фразами.

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

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


import NaturalLanguage

func getSemanticDistance(for word: String, in language: NLLanguage) {

// 1. Create the embedding for the language the word belongs to
if let embedding = NLEmbedding.wordEmbedding(for: language) {

// 2. Find the neighbors for the word
embedding.enumerateNeighbors(for: word, maximumCount: 10) { neighbor, distance in

// 3. Acces the neighbor distance from the word
print("\(neighbor): \(distance)")

return true
}
}
}
🔥32👍2
Faster iOS Networking with Shared Dictionary Compression

Сетевые задержки остаются проблемой для пользовательского опыта на iOS устройствах, и одним из способов улучшения этой ситуации является использование shared dictionary compression.

Что такое shared dictionary compression?

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

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

Однако, стоит понимать, что без доработок со стороны бекэнда данная практика невозможна 🫢
👍5🤯1
Корзина в Додо Пицце на iOS 14: баг длиной в полгода

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

Сама же проблема была простая: после редизайна приложения Додо Пиццы, кнопка корзины стала невидимой для пользователей на iOS 14, вызывая жалобы и проблемы с отображением стоимости продуктов. И фикс был в пару строк 🫣
👍51👎1🤔1🤬1
Beginner’s Guide to Protocol Buffers and gRPC with Swift

Отличная статья про Protocol Buffer или «protobuf», разбираются основные особенности его использования и gRPC.
Также автор описывает подробные шаги по настройке базового сервера gRPC в Swift с использованием библиотек Swift Protobuf и gRPC, включая создание структур данных Swift, создание интерфейса gRPC и внедрение интерфейса на стороне сервера.
Кстати, для сети он использует акторы и async/await.

func completeTodo(
request: ServerRequest<Todos_TodoID>,
context: ServerContext
) async throws -> ServerResponse<Todos_Todo> {
guard
var todo = todos.first(where: { $0.todoID == request.iss.onessage.todoID })
else {
return .init(
error: RPCError.init(
code: .notFound,
message: "Todo not found."
)
)
}
todo.completed = true
todos = todos.filter { $0.todoID != request.iss.onessage.todoID }
todos.append(todo)
return .init(message: todo)
}
🔥4
Азартная разработка iOS приложения игры 2048 с ChatGPT

Объемная и подробная статья про совместную разработку с ChatGPT известной игры 2048.

Также в игру вводится новый элемент: ИИ - алгоритм, который будет автоматически ходить. В качестве примера были взяты два: Monte Carlo и Expectimax

Все достаточно подробно описано и сопровождается обильным количеством скриншотов.
🔥4
Why Do View Controllers Need init(coder:)?

Класс UIViewController поддерживает протокол NSCoding, что требует реализации инициализатора init(coder:), даже если он не используется напрямую.

Даже при создании view controllers программно, необходимо использовать UIStoryboards, которые в процессе создания используют NSCoding для воссоздания состояния view controller и его представлений.
🔥2👎1
Swift TaskGroup на примерах

Если вы хотели разобраться в особенностях применения TaskGroup и чем она отличается от Task и async let, то эта статья для вас.

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

Также есть примеры работы с AsyncStream.
4🔥3🤬1
How Do Binaries work together? What breaks ABI?

Для успешной работы двух библиотек необходимо обеспечить совместимость как API (интерфейс программирования приложений), так и ABI (бинарный интерфейс приложений). Изменения, такие как удаление существующих функций, изменение их имен или добавление новых параметров, могут привести к нарушению ABI.

В статье достаточно подробно описан процесс работы ABI/API стабильности и какие изменения не приведут к нарушению.
🔥2
Тактильный отклик в мобильных приложениях: что это такое, когда использовать и зачем?

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

Рекомендуется использовать отклик для подтверждения действий, сигнализации об ошибках ввода и в игровых приложениях для создания погружающего опыта. Тактильные ощущения должны быть целенаправленными и не отвлекать пользователей. Важно создавать чёткую связь между действием и откликом, использовать тактильные ощущения экономно и не забывать о системных настройках устройства.
3🔥2
How to Use URLSession with Async/Await for Network Requests in Swift

URLSession позволяет выполнять сетевые запросы с использованием async/await, что упрощает процесс получения данных и их декодирования в структуру.

В статье разбираются примеры кода выполнения GET и POST запросов, декодирование JSON ответов, а также работа с типизированными ошибками для проверки различных HTTP кодов.

var urlComponents = URLComponents(string: "https://httpbin.org/get")!

/// Define the parameters.
let parameters: [String: String] = [
"name": "Antoine van der Lee",
"age": "33"
]

/// Add the query parameters to the URL.
urlComponents.queryItems = parameters.map { key, value in
URLQueryItem(name: key, value: value)
}

/// Ensure we have a valid URL and throw a URLError if it fails.
guard let url = urlComponents.url else {
throw URLError(.badURL)
}

/// Use URLSession to fetch the data asynchronously.
let (data, response) = try await URLSession.shared.data(from: url)
🔥5
Some vs Any

Apple советует начинать с some и использовать any только в случаях, когда не требуется ограничивать переменные одним типом.

some требует одинаковых типов возвращаемых значений, в то время как any позволяет использовать разные типы, что делает его менее строгим.

В этой статье намеренно не используются такие термины, как opaque, existential, boxed и type erasure, поскольку по мнению автора усложняют понимание сути.
🔥10
Automatic Trait Tracking

В iOS 18 UIKit автоматически отслеживает доступ к свойствам, устраняя необходимость вручную регистрироваться для уведомлений об изменениях свойств.

Автоматическое отслеживание поддерживается в методах обновления макета, таких как layoutSubviews(), updateViewConstraints() и draw(CGRect) для UIView, а также viewWillLayoutSubviews() и updateConfiguration для UIViewController и других.

Пример кода показывает, как в классе UIView автоматически изменяется размер рисуемого объекта в зависимости от выбранного размера шрифта доступности(dynamic type) без необходимости ручной регистрации изменений.
🔥3
The Case Against [unowned self]

В Swift существуют три типа ссылок: strong, weak и unowned. Сильные ссылки удерживают объект в памяти, слабые ссылки предотвращают циклы удержания, а unowned ссылки предполагают, что объект будет существовать дольше, чем ссылка.

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

Использование unowned может быть оправдано в системах с высокой нагрузкой или ограниченной памятью, но требует осторожности.
🔥7
This media is not supported in your browser
VIEW IN TELEGRAM
Integrating Live Activity and Dynamic Island in iOS: A Complete Guide

Большая и подробная статья про использование Live Activities и Dynamic Island.
Такие активити позволяют приложениям отображать актуальную информацию на экране блокировки, а Dynamic Island предоставляет интерактивную область для обновлений в верхней части экрана.

Live Activities могут быть активны до 8 часов, а их размер данных не должен превышать 4 КБ. Важно избегать перегрузки информацией и следовать рекомендациям по дизайну.

Для добавления поддержки Live Activity в приложение iOS необходимо создать расширение виджета и настроить Info.plist, добавив ключ 'Supports Live Activities'.
🔥7
MainActor usage in Swift explained to dispatch to the main thread

MainActor — это глобальный актор в Swift 5.5, который выполняет задачи на главном потоке, обеспечивая обновление пользовательского интерфейса без проблем с многопоточностью.

Использование @MainActor упрощает код, устраняя необходимость в множественных вызовах DispatchQueue.main.async и оптимизируя производительность, выполняя задачи на главном потоке только при необходимости.

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

Так, например, функция вида:
func fetchImage(for url: URL, completion: @escaping (Result<UIImage, Error>) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data, let image = UIImage(data: data) else {
DispatchQueue.main.async {
completion(.failure(ImageFetchingError.imageDecodingFailed))
}
return
}

DispatchQueue.main.async {
completion(.success(image))
}
}.resume()
}


Может превратиться в такую:
@MainActor
func fetchImage(for url: URL) async throws -> UIImage {
let (data, _) = try await URLSession.shared.data(from: url)
guard let image = UIImage(data: data) else {
throw ImageFetchingError.imageDecodingFailed
}
return image
}
👍6
Об анатомии крэшей на iOS «по-взрослому»

Большая и подробная Статья про причины и механизмы возникновения крэшей на iOS, включая ошибки в коде и проблемы с памятью (там на самом деле все «по-взрослому» 🫣)
Автор начинает со старта приложения и заканчивает разбором сигналов и исключений.

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

Достаточно серьезное чтиво 🤓
🔥6👍1
Дебаг на максимум: секретные настройки Xcode, которые должен знать каждый разработчик

Оптимизация графики в iOS требует понимания работы CPU и GPU, а также использования дебаг-инструментов для улучшения производительности приложений.

В Xcode доступны настройки, такие как Slow Animations, Graphics Quality Override и Simulate Memory Warning, которые помогают выявить и устранить проблемы с производительностью. Внеэкранная отрисовка может значительно замедлить работу GPU - её стоит избегать, используя кэширование и оптимизацию слоев.

Объемная и полезная статья про оптимизации графики в iOS.
🔥5
Асинхронность в iOS: как ускорить корпоративные приложения и не сломать мозг разработчика

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

Если очень коротко, то всего три:
- GCD (Grand Central Dispatch)
- Operation Queue
- Swift Concurrency

Речь идет про «коробочные решения» без погружения в глубину.
Но, кажется, мы все еще долго будем использовать gcd 🥲
❤‍🔥6
This media is not supported in your browser
VIEW IN TELEGRAM
Working with Natural Language framework

Я уже скидывал статью обзора работы с Natural Language. Однако, мимо этой не смог пройти мимо.

Очень крутой пример того, как можно воспользоваться возможностями этого фреймворка в комбинации с MeshGradient, который доступен с 18 iOS, для создания отзывчивого и красивого интерфейса 😲.
Осталось только придумать для чего это нужно 😅
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3😁2
Animate UIKit views with SwiftUI animations in iOS 18

В iOS 18 завезли поддержку анимаций SwiftUI для UIkit.

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

class ViewController: UIViewController {
...

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.startAnimating()
}

private func startAnimating() {
let animation = SwiftUI.Animation
.linear(duration: 1.3)
.repeatForever()

UIView.animate(animation) { [weak self] in
self?.animatingView?.transform = .init(scaleX: 2, y: 2)
}
}
}

Правда одно но: не все могут позволить себе апнуть минимальную поддерживаемую версию до 18 🫠
🔥8
Why Can't You Loop Over Ranges of Characters in Swift

Если пробовали вывести count у множества из символов в Swift и получали ошибку, то эта статья для вас 😅

Символы Юникода могут иметь разные порядки сортировки в зависимости от локали, что делает итерацию по диапазонам символов проблематичной. Еще некоторые символы, такие как эмодзи, могут состоять из нескольких кодовых блоков, что усложняет создание и итерацию по диапазонам.
🔥7