Прокачайте свой код с @dynamicMemberLookup
Атрибут dynamicMemberLookup в Swift позволяет обращаться к свойствам объекта, как если бы они были статически определены, что упрощает работу с динамическими структурами данных и делает API более гибким и расширяемым.
Но тут есть минус – компилятор не сможет подсказать вам, обращаетесь ли вы к существующему свойству или нет.
В статье разбираются основные моменты при работе с данным атрибутом на примере.
Атрибут dynamicMemberLookup в Swift позволяет обращаться к свойствам объекта, как если бы они были статически определены, что упрощает работу с динамическими структурами данных и делает API более гибким и расширяемым.
json[0]?["name"]?["first"]?.stringValue
// заменится на
json[0]?.name?.first?.stringValue
Но тут есть минус – компилятор не сможет подсказать вам, обращаетесь ли вы к существующему свойству или нет.
В статье разбираются основные моменты при работе с данным атрибутом на примере.
Хабр
Прокачайте свой Swift с @dynamicMemberLookup
Swift — это мощный язык программирования, который сочетает в себе безопасность типов и выразительность. Однако, несмотря на свою строгую типизацию, язык предоставляет разработчикам возможность...
🔥4
Data alignment: Straighten up and fly right
Хорошо проработанная статья на инженерном языке про работу процессора.
Главная мысль – раскрыть концепцию работы процессора: как он обращается к памяти в 2, 4, 8, 16 или 32-байтовых фрагментах, а не в байтовых кусках, как мы привыкли думать.
Хорошо проработанная статья на инженерном языке про работу процессора.
Главная мысль – раскрыть концепцию работы процессора: как он обращается к памяти в 2, 4, 8, 16 или 32-байтовых фрагментах, а не в байтовых кусках, как мы привыкли думать.
⚡3
UNSAFE SWIFT
Уже не новая, но актуальная статья про использование указателей в Swift.
Автор подробно разбирает выравнивание: для чего это может понадобиться, почему порядок типов в объекте имеет значение и как работать с объектами через один из 4 доступных указателей: UnsafeRawPointer, UnsafeMutableRawPointer, UnsafeRawBufferPointer и UnsafeMutableRawBufferPointer
Понимание того, как это работает важно для организации высокопроизводительного кода.
Уже не новая, но актуальная статья про использование указателей в Swift.
Автор подробно разбирает выравнивание: для чего это может понадобиться, почему порядок типов в объекте имеет значение и как работать с объектами через один из 4 доступных указателей: UnsafeRawPointer, UnsafeMutableRawPointer, UnsafeRawBufferPointer и UnsafeMutableRawBufferPointer
class Foo {
let a: UInt8
let b: UInt16
}
MemoryLayout<Foo>.size // 8
MemoryLayout<Foo>.alignment // 8
MemoryLayout<Foo>.stride // 8
Понимание того, как это работает важно для организации высокопроизводительного кода.
🔥11👀2
Как ускорить запуск iOS-приложения в 2 раза с помощью Network Instrument
Хорошая статья про борьбу с проблемами с сетью в приложениях: изменения порядка запросов, предварительное подключение, устранение редиректов и параллельная загрузка позволили ускорить старт приложения в два раза, сократив время ожидания пользователей.
В статье про использование Network Instrument, который позволяет выявить и решить множество проблем, например, неэффективное использование URLSession, блокирование запросов подключением, долгие редиректы и парсинг больших объемов данных.
Хорошая статья про борьбу с проблемами с сетью в приложениях: изменения порядка запросов, предварительное подключение, устранение редиректов и параллельная загрузка позволили ускорить старт приложения в два раза, сократив время ожидания пользователей.
В статье про использование Network Instrument, который позволяет выявить и решить множество проблем, например, неэффективное использование URLSession, блокирование запросов подключением, долгие редиректы и парсинг больших объемов данных.
Хабр
Как ускорить запуск iOS-приложения в 2 раза с помощью Network Instrument
Приложение — это соединение данных из сети с графическим интерфейсом. Про UI статей много, но про сеть почти никто не вспоминает, а ведь именно она влияет на время ожидания ответа пользователем. При...
🔥5
Как реализовать спойлер-эффект как в Telegram на Swift?
Очень хорошая статья с подробными разборами и комментариями о том, как создать вот такое:спойлер .
Для достижения нужного эффекта автор использует CAEmitterLayer. Однако, помимо лейера тут еще очень много различных тонкостей, которые с первого взгляда не очевидны.
Очень хорошая статья с подробными разборами и комментариями о том, как создать вот такое:
Для достижения нужного эффекта автор использует CAEmitterLayer. Однако, помимо лейера тут еще очень много различных тонкостей, которые с первого взгляда не очевидны.
Хабр
Как реализовать спойлер-эффект как в Telegram на Swift?
Спойлеры стали неотъемлемой частью общения в мессенджерах и социальных сетях. Они позволяют скрывать часть информации до тех пор, пока пользователь не захочет ее увидеть. В Telegram спойлер-эффект...
🔥4❤1
Beware UserDefaults: a tale of hard to find bugs, and lost data
Статья про неочевидные проблемы использования UserDefaults: автор столкнулся с необычным поведением, когда UserDefaults стал помечаться как данные, которые требуют шифрования и не доступны до разблокировки устройства. И пользовательские данные просто терялись.
Автор предлагает несколько решений, включая проверку isProtectedDataAvailable и использование собственной реализации UserDefaults для надежного доступа к данным.
Статья про неочевидные проблемы использования UserDefaults: автор столкнулся с необычным поведением, когда UserDefaults стал помечаться как данные, которые требуют шифрования и не доступны до разблокировки устройства. И пользовательские данные просто терялись.
Автор предлагает несколько решений, включая проверку isProtectedDataAvailable и использование собственной реализации UserDefaults для надежного доступа к данным.
Christianselig
Beware UserDefaults: a tale of hard to find bugs, and lost data
Excuse the alarmist title, but I think it’s justified, as it’s an issue that’s caused me a ton of pain in both support emails and actually tracking it down, so I want to make others aware of it so they don’t similarly burned.
Brief intro
For the uninitiated…
Brief intro
For the uninitiated…
🔥3
The perfect iOS networking layer does not exist - Part 1
Несмотря на название, автор приводит пример написания достаточно универсального и самодостаточного сетевого слоя.
Внутри используется async/await, а также внедряются промежуточные сущности для модификации уже собранных реквестов, например, логированием.
Несмотря на название, автор приводит пример написания достаточно универсального и самодостаточного сетевого слоя.
Внутри используется async/await, а также внедряются промежуточные сущности для модификации уже собранных реквестов, например, логированием.
calin.crist()
The perfect iOS networking layer does not exist - Part 1
Of course not. But there are great starting points to build a modular, extensible, and testable networking layer in iOS using Swift.
🔥5
The perfect iOS networking layer does not exist - Part 2
Продолжение статьи про написание сетевого слоя.
В этой части разбирается подход к тестированию уже написанного ранее слоя. Это часто бывает полезно и удобно, когда сам бекэнд еще не готов, а фронт уходит вперед. Покрытие самого клиента, сервиса запросов, а также middleware сущностей.
Будет полезным для тех, кто немного работал с тестами – дает базовое понимание о том, каким образом можно писать тесты.
Продолжение статьи про написание сетевого слоя.
В этой части разбирается подход к тестированию уже написанного ранее слоя. Это часто бывает полезно и удобно, когда сам бекэнд еще не готов, а фронт уходит вперед. Покрытие самого клиента, сервиса запросов, а также middleware сущностей.
Будет полезным для тех, кто немного работал с тестами – дает базовое понимание о том, каким образом можно писать тесты.
calin.crist()
The perfect iOS networking layer does not exist - Part 2
Of course not. But there are great starting points to build a modular, extensible, and testable networking layer in iOS using Swift. Part 2 covers unit and integration tests.
🔥3
Calculating the semantic distance between words with the Natural Language framework
Natural Language framework позволяет компьютерам понимать и взаимодействовать с человеческим языком, обрабатывать и анализировать текстовые данные, извлекать значимую информацию и понимать отношения между словами и фразами.
Класс NLEmbedding позволяет создавать векторное пространство, в котором строки представлены в виде векторов, и рассчитывать семантическое расстояние между словами, а также находить синонимы.
Это может понадобиться для создания приложений, которые анализируют текст на смысловые связи или создание чат ботов с адекватными ответами на запросы.
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
}
}
}
🔥3❤2👍2
Faster iOS Networking with Shared Dictionary Compression
Сетевые задержки остаются проблемой для пользовательского опыта на iOS устройствах, и одним из способов улучшения этой ситуации является использование shared dictionary compression.
Что такое shared dictionary compression?
Это метод сжатия, при котором клиент и сервер обмениваются копией некоторых данных (словаря), что позволяет уменьшить размер запросов.
Использование shared dictionary compression может привести к значительному улучшению времени загрузки, особенно для пользователей со слабыми или ненадежными сетевыми соединениями.
Однако, стоит понимать, что без доработок со стороны бекэнда данная практика невозможна 🫢
Сетевые задержки остаются проблемой для пользовательского опыта на iOS устройствах, и одним из способов улучшения этой ситуации является использование shared dictionary compression.
Что такое shared dictionary compression?
Это метод сжатия, при котором клиент и сервер обмениваются копией некоторых данных (словаря), что позволяет уменьшить размер запросов.
Использование shared dictionary compression может привести к значительному улучшению времени загрузки, особенно для пользователей со слабыми или ненадежными сетевыми соединениями.
Однако, стоит понимать, что без доработок со стороны бекэнда данная практика невозможна 🫢
👍5🤯1
Корзина в Додо Пицце на iOS 14: баг длиной в полгода
Интересная история фикса бага, который долго не могли отловить.
Иногда, даже самые некритичные баги могут подсказать слабые места в коде. А с учетом обновлений оси они могут возникать неожиданно и в самых неочевидных местах.
Сама же проблема была простая: после редизайна приложения Додо Пиццы, кнопка корзины стала невидимой для пользователей на iOS 14, вызывая жалобы и проблемы с отображением стоимости продуктов. И фикс был в пару строк 🫣
Интересная история фикса бага, который долго не могли отловить.
Иногда, даже самые некритичные баги могут подсказать слабые места в коде. А с учетом обновлений оси они могут возникать неожиданно и в самых неочевидных местах.
Сама же проблема была простая: после редизайна приложения Додо Пиццы, кнопка корзины стала невидимой для пользователей на iOS 14, вызывая жалобы и проблемы с отображением стоимости продуктов. И фикс был в пару строк 🫣
👍5❤1👎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.
Отличная статья про 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
Все достаточно подробно описано и сопровождается обильным количеством скриншотов.
Объемная и подробная статья про совместную разработку с ChatGPT известной игры 2048.
Также в игру вводится новый элемент: ИИ - алгоритм, который будет автоматически ходить. В качестве примера были взяты два: Monte Carlo и Expectimax
Все достаточно подробно описано и сопровождается обильным количеством скриншотов.
🔥4
Why Do View Controllers Need init(coder:)?
Класс UIViewController поддерживает протокол NSCoding, что требует реализации инициализатора init(coder:), даже если он не используется напрямую.
Даже при создании view controllers программно, необходимо использовать UIStoryboards, которые в процессе создания используют NSCoding для воссоздания состояния view controller и его представлений.
Класс UIViewController поддерживает протокол NSCoding, что требует реализации инициализатора init(coder:), даже если он не используется напрямую.
Даже при создании view controllers программно, необходимо использовать UIStoryboards, которые в процессе создания используют NSCoding для воссоздания состояния view controller и его представлений.
🔥2👎1
Swift TaskGroup на примерах
Если вы хотели разобраться в особенностях применения TaskGroup и чем она отличается от Task и async let, то эта статья для вас.
Приводятся примеры использования TaskGroup для решения конкурентных тасок, включая обработку ошибок, отмену операций и автоматическая отмена дочерних задач.
Также есть примеры работы с AsyncStream.
Если вы хотели разобраться в особенностях применения TaskGroup и чем она отличается от Task и async let, то эта статья для вас.
Приводятся примеры использования TaskGroup для решения конкурентных тасок, включая обработку ошибок, отмену операций и автоматическая отмена дочерних задач.
Также есть примеры работы с AsyncStream.
❤4🔥3🤬1
How Do Binaries work together? What breaks ABI?
Для успешной работы двух библиотек необходимо обеспечить совместимость как API (интерфейс программирования приложений), так и ABI (бинарный интерфейс приложений). Изменения, такие как удаление существующих функций, изменение их имен или добавление новых параметров, могут привести к нарушению ABI.
В статье достаточно подробно описан процесс работы ABI/API стабильности и какие изменения не приведут к нарушению.
Для успешной работы двух библиотек необходимо обеспечить совместимость как 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 кодов.
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