Разработка поиска по QR-коду в мобильном приложении
QR-код содержит структурированные данные: URL, контакт vCard, Wi-Fi credentials, платёжный запрос. Задача поиска по QR-коду — это парсинг содержимого и маршрутизация к нужному действию. Реализация проще, чем со штрих-кодами, но логика обработки контента требует продумывания.
Сканирование: самый короткий путь
iOS 16+: DataScannerViewController — системный сканер, требует одну строку настройки:
let scanner = DataScannerViewController(
recognizedDataTypes: [.barcode(symbologies: [.qr])],
qualityLevel: .balanced,
isHighlightingEnabled: true
)
isHighlightingEnabled: true добавляет визуальную подсветку найденного кода — пользователи это ценят.
iOS 14-15: VNDetectBarcodesRequest из Vision framework для фото, AVCaptureMetadataOutput для live-видео. Чуть больше кода, но логика та же.
Android: ML Kit BarcodeScanning.getClient() с BarcodeScannerOptions — указываем FORMAT_QR_CODE для оптимизации скорости. Если нужны все форматы — убираем фильтр, но это чуть медленнее.
Парсинг и маршрутизация
QR-код — это строка. Что с ней делать — зависит от содержимого:
- Начинается с
http://илиhttps://→ открываем вSFSafariViewController/CustomTabs -
WIFI:S:NetworkName;T:WPA;P:password;;→ предлагаем подключиться к Wi-Fi (на iOS черезNEHotspotConfiguration, на Android черезWifiNetworkSuggestion) -
BEGIN:VCARD→ парсим черезCNContactVCardSerialization(iOS) илиVCardReader(Android) - Внутренний формат приложения → кастомная обработка
Регулярки для определения типа работают, но хрупко. Лучше — ML Kit на Android автоматически определяет тип через Barcode.valueType (URL, WIFI, CONTACT_INFO и др.). На iOS VNBarcodeObservation.payloadStringValue возвращает сырую строку — тип придётся определять самостоятельно.
Работа с галереей
Пользователи ожидают, что можно выбрать QR-код из фото в галерее, не только сканировать с камеры. Реализация:
iOS: PHPickerViewController → получаем UIImage → VNDetectBarcodesRequest на CIImage. Работает синхронно или через perform в фоновом потоке.
Android: ActivityResultContracts.GetContent("image/*") → получаем Uri → InputImage.fromFilePath(context, uri) → BarcodeScanning.getClient().process(inputImage).
Частая ошибка: обработка изображения на main thread. На фото из галереи это блокирует UI на 200-500ms. Всегда — в фоновый поток.
Срок разработки: 1-2 дня. Стоимость рассчитывается индивидуально.







