Реалізація сканування QR-кодів через камеру мобільного застосунку
DataScannerViewController на iOS 16+ зробила реалізацію QR-сканера тривіальним завданням — приблизно 20 рядків коду. На Android ML Kit справляється аналогічно. Основна робота — UX навколо сканера: підсвітка, анімація, обробка помилок доступу до камери.
iOS: два шляхи
DataScannerViewController (iOS 16+)
guard DataScannerViewController.isSupported,
DataScannerViewController.isAvailable else { return }
let scanner = DataScannerViewController(
recognizedDataTypes: [.barcode(symbologies: [.qr])],
qualityLevel: .balanced,
recognizesMultipleItems: false,
isHighlightingEnabled: true
)
scanner.delegate = self
try? scanner.startScanning()
present(scanner, animated: true)
recognizesMultipleItems: false — зупиняється на першому знайденому коді. isHighlightingEnabled малює рамку навколо коду автоматично.
Делегат:
func dataScanner(_ dataScanner: DataScannerViewController,
didAdd addedItems: [RecognizedItem],
allItems: [RecognizedItem]) {
guard case let .barcode(barcode) = addedItems.first,
let payload = barcode.payloadStringValue else { return }
dataScanner.stopScanning()
handleQR(payload)
}
AVFoundation (iOS 14-15)
Для підтримки iOS 14-15 — AVCaptureMetadataOutput із metadataObjectTypes = [.qr]. Детальна реалізація така сама, як для загального сканування штрих-кодів.
Android: ML Kit в 10 рядків
val options = BarcodeScannerOptions.Builder()
.setBarcodeFormats(Barcode.FORMAT_QR_CODE)
.build()
val scanner = BarcodeScanning.getClient(options)
Через CameraX ImageAnalysis — той самий підхід, що й для загального сканування штрих-кодів. Вказання конкретного формату FORMAT_QR_CODE прискорює розпізнавання приблизно вдвічі порівняно з FORMAT_ALL_FORMATS.
Що реально вимагає часу: UI навколо сканера
Оверлей із прицілом. Стандартний паттерн — напівпрозорий оверлей із прозорим прямокутником у центрі. На iOS: CAShapeLayer із evenOdd fill rule або SwiftUI Canvas. На Android: користувацький View із PorterDuff.Mode.CLEAR.
Анімація скануючої лінії. Користувачі очікують рухому лінію — без неї незрозуміло, чи іде процес. Проста CABasicAnimation на iOS або ObjectAnimator на Android.
Ліхтарик. Переключення фонарика: на iOS AVCaptureDevice.torchMode = .on, на Android CameraControl.enableTorch(true).
Дозвіл камери. Якщо користувач відхилив запит, стандартний флоу: AVCaptureDevice.authorizationStatus(for: .video) == .denied → кнопка «Відкрити налаштування» → UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!). На Android — ActivityCompat.shouldShowRequestPermissionRationale() для пояснення.
Час реалізації: 1 день (базова функція) — 2 дні (із користувацьким UI та обробкою всіх edge cases). Вартість розраховується індивідуально.







