Вышла наша статья про то, как мы делали стенд для ИТ Пикника: с on-device распознаванием номеров телефонов. Это было увлекательное путешестевие с безумными ограничениями, как по времени, так и по нефунциональным требованиям, с возможностью затестить разные технологии, фреймворки, но при этом сделать стенд и продукт технологичным и крутым. И мы с этим точно справились: "умная камера" распознавала номера телефонов в среднем в 7,5 раз быстрее человека, который вводил этот номер руками. Вы только навели телефон и уже получаете результат
В статье про:
- как мы делали клиент-серверное приложение без доступа к интернету
- почему мы выбрали свою модель и что не так было с vision в нашем случае
- с какими проблемами мы столкнулись и почему перегрев устройств - это серьезная проблема
- и, конечно же, про особенности computer vision с on-device спецификой.
С вас лайк, репост, подписка 😊
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9
How to bundle assets in an iOS app?
С iOS 16 Apple представила фреймворк
👉 Фреймворк позволяет обновлять игры и ресурсы без повторной отправки приложения на проверку, а также устраняет ограничения по размеру, ранее установленные для
👉 Разработчики должны определить необходимые файлы, добавить ключи в
❗️ Необходимо быть осторожным с выбором файлов для загрузки, так как их URL могут быть подделаны, что может привести к утечкам данных.
⚠️ Тестирование фреймворка требует отправки приложения на проверку.
С iOS 16 Apple представила фреймворк
Background Assets, который позволяет разработчикам хранить и автоматически загружать ресурсы приложений вне App Store, улучшая время загрузки и уменьшая размер приложения.On-Demand Resources.info.plist и создать манифест для управления загрузками, чтобы обеспечить корректную работу фреймворка.Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
objc async selectors
Если вдруг вы захотите сделать objc метод для селектора async - не стоит❌
Автор разбирает похожую ситуацию, где он пометил похожий метод как async:
Также автор разбирает возможную причину такого поведения и вариант обхода такой проблемы.
Если вдруг вы захотите сделать objc метод для селектора async - не стоит
Автор разбирает похожую ситуацию, где он пометил похожий метод как async:
let button = UIButton(frame: buttonFrame)
view.addSubview(button)
button.setTitle("This is a button", for: .normal)
button.addTarget(
self,
action: #selector(handleTap),
for: .touchUpInside
)
@objc func handleTap() async {
Task {
debugPrint("handle Tap")
}
}
И в итоге получил краш. Также автор разбирает возможную причину такого поведения и вариант обхода такой проблемы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Static, Dynamic, Mergeable, oh, my!
Статья для тех, кто хотел разобраться в разных типах ликовки библиотек.💡
👉 Линковка — это процесс объединения скомпилированных объектных файлов в единое исполняемое приложение, который может происходить статически или динамически. Отсюда два разных типа библиотек: статические и динамические.
🔗 Статическая линковка улучшает время загрузки приложения, но чаще всего приводит к увеличению размера приложения, тогда как динамическая линковка уменьшает размер, но может замедлить время запуска.
😮 В Xcode 15 появились mergeable библиотеки. Они позволяют динамически линковать библиотеки в отладочных сборках и статически в релизных, что улучшает производительность разработки и запуска.
✔️ Понимание работы линковщика позволяет оптимизировать размер приложения, упростить граф зависимостей и улучшить время сборки.
Статья для тех, кто хотел разобраться в разных типах ликовки библиотек.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Core Location Modern API Tips
Пару советов по работе с👉 Рекомендуется использовать
👉 Для приложений с целевой версией iOS 18.0 и выше предпочтительно использовать
👉 Для работы в фоновом режиме необходимо добавить соответствующие ключи в настройки приложения и использовать
👉 Для симуляции перемещения можно использовать GPX файлы, однако могут возникнуть проблемы с выбором файлов в Xcode, которые можно решить, изменив настройки системы.
Пару советов по работе с
Core Location:
CLLocationManager вместо CLMonitor и CLLocationUpdate, так как он предлагает больше возможностей и меньше проблем с совместимостью.CLServiceSession, так как он упрощает управление разрешениями на использование местоположения.CLBackgroundActivitySession для получения обновлений местоположения.Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
How to unit test async/await functions in Swift
Тестирование функций async/await в Swift стало проще благодаря отсутствию необходимости в XCTestExpectation, достаточно просто пометить тестовую функцию как async и использовать await.
Для функций, которые могут выбрасывать ошибки, можно использовать ключевое слово try, а также обрабатывать ошибки с помощью блока do-catch для более точного контроля над тестами.
Тестирование функций async/await в Swift стало проще благодаря отсутствию необходимости в XCTestExpectation, достаточно просто пометить тестовую функцию как async и использовать await.
Для функций, которые могут выбрасывать ошибки, можно использовать ключевое слово try, а также обрабатывать ошибки с помощью блока do-catch для более точного контроля над тестами.
func testFibonacciSequenceThrowsError() async throws {
do {
let _ = try await fibonacciSequence(count: -1)
XCTFail("Expected an error for negative count, but no error was thrown")
} catch FibonacciError.invalidCount {
// Success! The expected error was thrown.
} catch {
XCTFail("Unexpected error thrown: \(error)")
}
}👍3
XCTest Meets @MainActor: How to Fix Strict Concurrency Warnings
Если вы попробовали поддержать Swift 6 в своем проекте, то в тестах у вас могла произойти картина, схожая со скриншотом - куча ворнингов, которые станут ошибками в Swift 6.
Тут есть несколько вариантов решения:
💡 Для устранения предупреждений можно пометить класс тестов как
⚙️ Можно также попробовать использовать асинхронные версии методов
➡️ Альтернативно - старайтесь избегать использования
Если вы попробовали поддержать Swift 6 в своем проекте, то в тестах у вас могла произойти картина, схожая со скриншотом - куча ворнингов, которые станут ошибками в Swift 6.
Тут есть несколько вариантов решения:
@MainActor, что позволяет избежать ошибок, связанных с различиями в изоляции актора.setUp и tearDown, чтобы избежать предупреждений о синхронном контексте.setUp и tearDown, создавая объекты непосредственно в тестах, или перейти на Swift Testing для лучшей совместимости с актерами.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4❤2
Model Inheritance in Core Data
🔗 Core Data позволяет разработчикам использовать модель наследования, что упрощает создание и управление данными, позволяя подчинённым сущностям наследовать свойства родительской сущности.
🟢 Модель наследования упрощает декларации моделей, поддерживает агрегированные запросы и улучшает гибкость в моделировании отношений между различными подтипами сущностей.
⚠️ Несмотря на преимущества, такая модель может привести к избыточности данных и снижению производительности при работе с большими объемами данных.
📌 Рекомендуется осторожно использовать модель наследования и рассмотреть возможность ручной реализации аналогичных эффектов для лучшей совместимости с SwiftData.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Getting started with Core Image
➡️ Фреймворк состоит из трех основных компонентов:
🖥 ⚙️ Фреймворк использует аппаратное ускорение через GPU для высокопроизводительных задач, что позволяет обрабатывать изображения быстро и эффективно, особенно в приложениях, требующих реального времени.
Core Image — это мощный фреймворк для обработки и анализа изображений, разработанный Apple, который позволяет разработчикам применять фильтры и выполнять сложные манипуляции с изображениями в реальном времени.CIImage (представляет данные изображения), CIFilter (применяет эффекты) и CIContext (управляет рендерингом изображений).Core Image предлагает широкий набор встроенных фильтров, которые можно комбинировать для создания сложных эффектов, а также возможность создания пользовательских фильтров с использованием языка Core Image Kernel или Metal.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
How combine lists of Strings into natural and localized sentences in Swift
✏️ Класс
💡 Метод
😮
✔️ Метод
ListFormatter позволяет объединять списки строк в читаемые предложения, учитывая локализацию пользователя.
// Используя joined
let languages = ["Swift", "Kotlin", "Rust"]
let joinedLanguages = languages.dropLast().joined(separator: ", ")
+ (languages.count > 1 ? " and " : "")
+ (languages.last ?? "")
// "Swift, Kotlin and Rust"
// Используя ListFormatter
let listFormatter = ListFormatter()
// "Swift, Kotlin, and Rust"
listFormatter.string(from: ["Swift", "Kotlin", "Rust"])
string(from:) класса ListFormatter преобразует массив элементов в строку, учитывая локаль, например, 'Swift, Kotlin y Rust' для испанского языка.let listFormatter = ListFormatter()
listFormatter.locale = Locale(identifier: "es-ES")
// "Swift, Kotlin y Rust"
listFormatter.string(from: ["Swift", "Kotlin", "Rust"])
ListFormatter может работать не только со строками, но и с любыми типами, которые могут быть представлены как строки, при этом пользовательские типы должны соответствовать протоколу CustomStringConvertible.formatted на массиве строк предлагает более лаконичный способ форматирования списков с дополнительными параметрами, такими как тип соединения (например, 'или' или 'и').Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1
Network Link Conditioner: Simulating Slow Networking
👀 Если вы не знали как тестировать состояния сетевого соединения, то эта статья для вас.
⌛ Network Link Conditioner позволяет тестировать приложения в условиях медленной сети на macOS и iOS, предлагая профили, такие как 3G и Edge.
⚙️ На iOS Network Link Conditioner доступен в разделе инструментов разработчика в настройках, где можно выбрать предустановленный профиль или создать свой.
⚙️ Чтобы установить Network Link Conditioner на macOS, необходимо загрузить дополнительные инструменты для Xcode через меню Xcode и найти его в папке Hardware.
➡️ Тестирование приложений в условиях медленной сети критически важно для обеспечения хорошего пользовательского опыта, особенно для пользователей с низкой скоростью интернета.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Потоки под капотом: как работают многопоточность и синхронизация в iOS
Если хотели разобраться в многопоточности - статья для вас - все достаточно хорошо и понятно написано.
Ниже приведу пару тезисов.
🕯 Конкурентность подразумевает чередование выполнения задач, в то время как параллелизм требует наличия нескольких процессорных ядер для одновременного выполнения задач.
ℹ️ Процесс — это экземпляр запущенной программы, который может содержать несколько потоков, выполняющихся в одном адресном пространстве, что позволяет эффективно управлять ресурсами.
⚙️ iOS предлагает инструменты, такие как GCD и Swift Concurrency, для управления потоками и задачами, обеспечивая оптимальное распределение ресурсов и упрощая разработку многопоточных приложений.
📊 Закон Амдала описывает, что ускорение программы, достигнутое за счет параллельной обработки, ограничено последовательными участками кода, которые не могут быть распараллелены.
Если хотели разобраться в многопоточности - статья для вас - все достаточно хорошо и понятно написано.
Ниже приведу пару тезисов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
How to create and upload high-quality App Store assets with RocketSim and Helm
👀 Недавно вспоминали RocketSim. Держите статью, про упрощение создания качественных изображений для AppeSrore.
💡 RocketSim предлагает инструменты для создания оптимизированных скриншотов и видео-превью, что помогает выделить уникальные функции вашего приложения.
⭐️ Helm автоматизирует загрузку скриншотов, позволяя перетаскивать их из Finder и автоматически сортируя по устройствам и языкам.
➡️ Поддержка загрузки видео-превью в Helm запланирована на будущее.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
Introducing gRPC Swift 2
🔝 gRPC Swift 2: Что нового и зачем это нужно?
Вышла вторая версия gRPC Swift — теперь с нативной поддержкой async/await и глубокой интеграцией в SwiftNIO. Это делает асинхронные RPC-вызовы проще, а код — чище, без ада с коллбэками.
⚡️ gRPC Swift 2 поддерживает все фичи протокола: от стримов до метаданных, плюс кодогенерация из .proto-файлов. Включает в себя умные функции клиента, такие как балансировка нагрузки, механизм разрешения имен и автоматические повторные попытки.
⚙️ gRPC Swift 2 распределен как набор пакетов, позволяя разработчикам выбирать только те компоненты, которые им необходимы.
Вышла вторая версия gRPC Swift — теперь с нативной поддержкой async/await и глубокой интеграцией в SwiftNIO. Это делает асинхронные RPC-вызовы проще, а код — чище, без ада с коллбэками.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9
Swift 6: What’s New and How to Migrate
⚠️ Статья Antoine van der Lee
— гайд по апдейту проектов и пакетов под Swift 6. Акцент на настройке Xcode, обработке предупреждений и переходе на новую модель конкурентности.
⚙️ Подсветка ключевых параметров: включаем
➡️ Рекомендуется поэтапная миграция проектов, начиная с изолированных частей кода, с поэтапным включением новых функций и строгой проверки параллелизма.
💡 Не спешите, исправляйте предупреждения по мере их появления и открывайте запросы на изменения для небольших изменений, чтобы упростить процесс.
— гайд по апдейту проектов и пакетов под Swift 6. Акцент на настройке Xcode, обработке предупреждений и переходе на новую модель конкурентности.
-strict-concurrency=complete и фиксим deprecated-методы. Автор советует не откладывать миграцию — Swift 6 ломает обратную совместимость в угоду безопасности.Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
@unknown default usage with enums in Swift
⚠️ Конструкция
❓ Когда использовать?
Если enum может расширяться без вашего контроля (например, серверные модели). Для своих enum хватит обычного
➡️
@unknown default была введена в Swift 5 для работы с перечислениями и помогает подготовиться к будущим изменениям API от Apple.enum AppState: CaseIterable {
case active, background
@unknown default // На случай, если в Swift 6 добавят новый кейс
}
func handle(state: AppState) {
switch state {
case .active: print("App alive!")
case .background: print("App sleep...")
@unknown default: print("WARNING: New state detected!")
}
}Если enum может расширяться без вашего контроля (например, серверные модели). Для своих enum хватит обычного
default — иначе потеряете в читаемости.Frozen перечисления никогда не получат новых случаев, в то время как non-frozen перечисления требуют использования @unknown для обработки будущих случаев.Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Creating ML models with Create ML
😮
➡️ Сам
❗️ Качество набора данных критично для успешного обучения модели - иначе модель выдаст «мусор на выходе»; можно использовать методы увеличения данных для улучшения результатов. После обучения можно просмотреть результаты точности модели и протестировать её на примерах текста.
Краткий вывод:
✔️ Если нужно быстро внедрить ML в приложение без сложных кастомных моделей -
Create ML — это инструмент для создания моделей машинного обучения без необходимости написания кода, доступный в Xcode. Интерфейс вместо тысячи строк кода: классификация изображений, текста или тайм-серий. В статье приведены советы по импорту данных и оценке точности без танцев с Python. CreateML поддерживает различные алгоритмы, включая BERT, который подходит для многоязычных моделей и улучшает понимание контекста.Краткий вывод:
CreateML отличное решение. Для глубоких экспериментов — всё же используйте более специализированные инструменты.Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Using Critical Alerts in iOS applications
Если вы не знал про
⚠️
🖥 Для использования
➡️ При запросе разрешений на уведомления необходимо добавить опцию .
🔈 Для отправки
⚙️ С помощью расширения службы уведомлений можно изменить входящие уведомления на критические, изменив свойство
🚨 Но обращаю внимание: Нужно обосновать необходимость применения таких алертов в личном кабинете разработчика.
Если вы не знал про
Critical Alerts в iOS - советую ознакомиться. Critical Alerts в iOS показываются пользователю даже в беззвучном режиме или режиме Не беспокоить, что делает их очень заметными. Фишка для медприложений, систем безопасности или экстренных оповещений. Critical Alert необходимо получить специальные разрешения от Apple через портал разработчиков, добавив ключ com.apple.developer.usernotifications.critical-alerts в файл entitlements.criticalAlert, чтобы пользователь мог отдельно разрешить или запретить критические уведомления.Critical Alert необходимо изменить payload, указав звук как критический в формате словаря.sound в UNMutableNotificationContent.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍2