How to Use URLSession with Async/Await for Network Requests in Swift
URLSession позволяет выполнять сетевые запросы с использованием async/await, что упрощает процесс получения данных и их декодирования в структуру.
В статье разбираются примеры кода выполнения GET и POST запросов, декодирование JSON ответов, а также работа с типизированными ошибками для проверки различных HTTP кодов.
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, поскольку по мнению автора усложняют понимание сути.
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) без необходимости ручной регистрации изменений.
В 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 может быть оправдано в системах с высокой нагрузкой или ограниченной памятью, но требует осторожности.
В 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'.
Большая и подробная статья про использование 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, не всегда гарантируют выполнение на главном потоке, если они вызываются синхронно из фонового потока.
Так, например, функция вида:
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, включая ошибки в коде и проблемы с памятью (там на самом деле все «по-взрослому» 🫣)
Автор начинает со старта приложения и заканчивает разбором сигналов и исключений.
Также предлагаются различные методы диагностики и отладки, которые помогут разработчикам выявлять и устранять проблемы, приводящие к сбоям.
Достаточно серьезное чтиво 🤓
Большая и подробная Статья про причины и механизмы возникновения крэшей на iOS, включая ошибки в коде и проблемы с памятью (там на самом деле все «по-взрослому» 🫣)
Автор начинает со старта приложения и заканчивает разбором сигналов и исключений.
Также предлагаются различные методы диагностики и отладки, которые помогут разработчикам выявлять и устранять проблемы, приводящие к сбоям.
Достаточно серьезное чтиво 🤓
🔥6👍1
Дебаг на максимум: секретные настройки Xcode, которые должен знать каждый разработчик
Оптимизация графики в iOS требует понимания работы CPU и GPU, а также использования дебаг-инструментов для улучшения производительности приложений.
В Xcode доступны настройки, такие как Slow Animations, Graphics Quality Override и Simulate Memory Warning, которые помогают выявить и устранить проблемы с производительностью. Внеэкранная отрисовка может значительно замедлить работу GPU - её стоит избегать, используя кэширование и оптимизацию слоев.
Объемная и полезная статья про оптимизации графики в iOS.
Оптимизация графики в 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 🥲
Короткая статья, где по полочкам разложены отличия основных подходов к решению задач многопоточности.
Если очень коротко, то всего три:
- 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, для создания отзывчивого и красивого интерфейса😲 .
Осталось только придумать для чего это нужно 😅
Я уже скидывал статью обзора работы с 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 много крутых анимаций из коробки.
Делается довольно просто:
В 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 и получали ошибку, то эта статья для вас 😅
Символы Юникода могут иметь разные порядки сортировки в зависимости от локали, что делает итерацию по диапазонам символов проблематичной. Еще некоторые символы, такие как эмодзи, могут состоять из нескольких кодовых блоков, что усложняет создание и итерацию по диапазонам.
Если пробовали вывести count у множества из символов в Swift и получали ошибку, то эта статья для вас 😅
Символы Юникода могут иметь разные порядки сортировки в зависимости от локали, что делает итерацию по диапазонам символов проблематичной. Еще некоторые символы, такие как эмодзи, могут состоять из нескольких кодовых блоков, что усложняет создание и итерацию по диапазонам.
🔥7
The power and expressiveness of Swift ranges
В Swift существуют различные типы диапазонов: ClosedRange, Range, PartialRangeThrough, PartialRangeFrom и PartialRangeUpTo, каждый из которых имеет свои уникальные характеристики и ограничения.
Если хотели разобраться с особенностями их применения - это хорошая обзорная статья.
Для примера:
В Swift существуют различные типы диапазонов: ClosedRange, Range, PartialRangeThrough, PartialRangeFrom и PartialRangeUpTo, каждый из которых имеет свои уникальные характеристики и ограничения.
Если хотели разобраться с особенностями их применения - это хорошая обзорная статья.
Для примера:
let closedRange = Int.min...3
let partialRange = ...3
let numbers = [10, 20, 30, 40, 50, 60, 70]
print(numbers[closedRange]) // 💣💣💣 ERROR: Negative Array index is out of range
let numbers = [10, 20, 30, 40, 50, 60, 70]
print(numbers[partialRange]) // from the first index in the sequence, all the way to index: 3
// Prints "[10, 20, 30, 40]"
🔥6
Use cases for self, Self and Self.self in Swift
В Swift мы можем применять self, Self и Self.self. Как понять когда - поможет статья, в которой разбираются особенности применения на примерах.
• self используется для доступа к свойствам и методам экземпляра внутри его собственных методов.
• Self с заглавной буквы обозначает тип, который соответствует протоколу, позволяя реализовать полиморфное поведение.
• Self.self используется для обращения к метатипу, что позволяет выполнять операции на уровне типа.
В Swift мы можем применять self, Self и Self.self. Как понять когда - поможет статья, в которой разбираются особенности применения на примерах.
• self используется для доступа к свойствам и методам экземпляра внутри его собственных методов.
• Self с заглавной буквы обозначает тип, который соответствует протоколу, позволяя реализовать полиморфное поведение.
• Self.self используется для обращения к метатипу, что позволяет выполнять операции на уровне типа.
protocol Registrable {
static func register()
}
extension Registrable {
static func register() {
print("Registering \(Self.self)")
}
}
class Service: Registrable {}
// Prints `Registering Service`
Service.register()
🔥10❤3
Secure your URLSession network requests using Certificate Pinning
SSL Pining необходим не только для защиты от MITM атак, но и для обхода ограничений доверенных сертификатов при обращении на бэкэнд.
В данной статье автор рассказывает, как получить сертификат и какую обвязку нужно написать для того, чтобы запросы работали с SSL Pining.
SSL Pining необходим не только для защиты от MITM атак, но и для обхода ограничений доверенных сертификатов при обращении на бэкэнд.
В данной статье автор рассказывает, как получить сертификат и какую обвязку нужно написать для того, чтобы запросы работали с SSL Pining.
private extension HTTPClient: URLSessionDelegate {
/// Handles server authentication challenges for Certificate Pinning.
func urlSession(
_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
) {
// We will write our pinning business logic here.
}
}
🔥5❤2
BDUI — это спасение от релизов: «Какие ваши доказательства?»
BDUI (Backend Driven User Interface) позволяет делегировать построение интерфейса серверу, что снижает количество релизов и затраты на разработку новых функций.
Ключевые преимущества BDUI включают консистентность интерфейсов, единую базу конфигураций и отсутствие необходимости в релизах для добавления новых функций.
Основные недостатки BDUI включают ограничения в дизайне, необходимость релизов для новых компонентов и длительное время разработки на старте.
Использование BDUI значительно улучшает время от идеи до реализации (TTM), позволяя быстрее вносить изменения через редактирование JSON-конфигураций.
BDUI (Backend Driven User Interface) позволяет делегировать построение интерфейса серверу, что снижает количество релизов и затраты на разработку новых функций.
Ключевые преимущества BDUI включают консистентность интерфейсов, единую базу конфигураций и отсутствие необходимости в релизах для добавления новых функций.
Основные недостатки BDUI включают ограничения в дизайне, необходимость релизов для новых компонентов и длительное время разработки на старте.
Использование BDUI значительно улучшает время от идеи до реализации (TTM), позволяя быстрее вносить изменения через редактирование JSON-конфигураций.
👍4❤🔥2🔥2🤬1
Finding unused code with Periphery
Periphery — это command-line инструмент для поиска неиспользуемого кода в проектах на Swift, который помогает поддерживать чистоту кода без значительных затрат времени.
Автор приводит в пример свою работу с приложением Muse, в котором больше 350 000 строк кода на Swift.
В общем, если хотели почистить свою кодовую базу, самое время это сделать 🫡
Periphery — это command-line инструмент для поиска неиспользуемого кода в проектах на Swift, который помогает поддерживать чистоту кода без значительных затрат времени.
Автор приводит в пример свою работу с приложением Muse, в котором больше 350 000 строк кода на Swift.
В общем, если хотели почистить свою кодовую базу, самое время это сделать 🫡
🔥4👍2
Swift Language focus areas heading into 2025
Не так давно LSG - Language Steering Group - анонсировала основные фокусные направления на 2025 год:
👉 Несмотря на сильную основу Swift Concurrency в версии 6.0, многие разработчики испытывают трудности с его внедрением, и группа по управлению языком рассматривает идеи для упрощения этого процесса.
👉 Работа над типами Span позволит безопасно читать и записывать массивы объектов в памяти без необходимости управления памятью, что улучшит производительность и безопасность кода.
👉 Swift будет улучшать взаимодействие с C++ через поддержку некопируемых и неуходящих типов, а также разрабатывается библиотечное решение для прямого взаимодействия с Java.
Не так давно LSG - Language Steering Group - анонсировала основные фокусные направления на 2025 год:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
What are Sendable and @Sendable closures in Swift?
Протокол Sendable и аннотация @Sendable помогают компилятору проверять, может ли объект безопасно передаваться через границы конкурентности, предотвращая состояния гонки.
Структуры и акторы в Swift являются Sendable по умолчанию, если все их члены также соответствуют требованиям Sendable, в то время как классы требуют явного соответствия.
Для классов, которые не могут быть помечены как Sendable, можно использовать @unchecked Sendable, но это требует осторожности, так как это может привести к проблемам с безопасностью потоков.
Протокол Sendable и аннотация @Sendable помогают компилятору проверять, может ли объект безопасно передаваться через границы конкурентности, предотвращая состояния гонки.
Структуры и акторы в Swift являются Sendable по умолчанию, если все их члены также соответствуют требованиям Sendable, в то время как классы требуют явного соответствия.
Для классов, которые не могут быть помечены как Sendable, можно использовать @unchecked Sendable, но это требует осторожности, так как это может привести к проблемам с безопасностью потоков.
// This struct is not sendable
struct Movie {
let formatterCache = FormatterCache() // This is class
let releaseDate = Date()
var formattedReleaseDate: String {
let formatter = formatterCache.formatter(for: "YYYY")
return formatter.string(from: releaseDate)
}
}
// This struct is sendable
struct Movie {
var formattedReleaseDate = "2022"
}
👍4
Sending vs Sendable in Swift
Swift 6 вводит новый ключевое слово
В статье приведены примеры кода, показывающие, как использовать
Swift 6 вводит новый ключевое слово
sending
, которое заменяет @Sendable
для обеспечения безопасности передачи замыканий и значений между контекстами изоляции.Sendable
позволяет передавать только безопасные для многопоточного доступа объекты, в то время как sending
позволяет передавать объекты, которые не могут быть использованы после захвата в замыкании.В статье приведены примеры кода, показывающие, как использовать
sending
и @Sendable
в Swift 6, а также объясняется, как компилятор обрабатывает ошибки при неправильном использовании.func exampleFunc() async {
let isNotSendable = MyClass()
// Value of non-Sendable type ... accessed after being transferred;
// later accesses could race
Task {
isNotSendable.count += 1
}
// Access can happen concurrently
print(isNotSendable.count)
}
👍5🤯1🤬1