iOS приложение для сканирования штрих-кодов EAN-8 и EAN-13 с использованием камеры устройства. Демонстрирует интеграцию UIKit компонентов в SwiftUI через UIViewControllerRepresentable и работу с AVFoundation.
- Захватывает видео с камеры и распознаёт штрих-коды форматов EAN-8 и EAN-13
- Отображает отсканированный код на экране с цветовой индикацией (красный/зелёный)
- Показывает понятные алерты при ошибках (нет доступа к камере / неверный формат)
- Использует архитектуру MVVM с Delegate pattern для связи UIKit ↔ SwiftUI
Model - данные и их структура (CameraError, AlertItem)
View - SwiftUI экраны (BarcodeScannerView, ScannerView)
ViewModel - управление состоянием (BarcodeScannerViewModel)
Coordinator - мост между UIKit и SwiftUI (ScannerView.Coordinator)
- Пользователь запускает приложение
ScannerViewController(UIKit) настраиваетAVCaptureSessionи начинает захват с камеры- Когда баркод распознан,
AVCaptureMetadataOutputObjectsDelegateполучает данные - Делегат вызывает
Coordinator, который обновляет@Publishedсвойства вViewModel - SwiftUI автоматически обновляет UI (показывает код или алерт)
AVCaptureSessionзахватывает видео с камерыAVCaptureMetadataOutputобнаруживает баркодmetadataOutput(_:didOutput:)вызывается с данными баркода- Через делегат →
Coordinator→ устанавливаетсяscannedCodeв ViewModel @Publishedтриггерит обновление, SwiftUI показывает код на экране
При ошибках (нет камеры / неверный формат) аналогично через делегат устанавливается alertItem, и SwiftUI показывает .alert().
Важно: все изменения состояния обёрнуты в DispatchQueue.main.async для предотвращения "Modifying state during view update".
- Xcode 16.2+
- iOS 18.2+
- Физическое устройство (симулятор не имеет камеры!)
- Клонируйте репозиторий
git clone <repository-url> cd Barcode-Scanner
- Откройте
BarcodeScanner.xcodeproj - Подключите iPhone/iPad
- Выберите устройство и запустите (⌘R)
💡 При первом запуске система запросит разрешение на доступ к камере
- Swift 5.0
- SwiftUI - декларативный UI,
@StateObject,@Published,@Binding - UIKit -
UIViewController,UIViewControllerRepresentable - AVFoundation -
AVCaptureSession,AVCaptureMetadataOutput,AVCaptureVideoPreviewLayer - Delegate Pattern - для передачи событий из UIKit в SwiftUI
- Concurrency -
DispatchQueueдля управления потоками
Протокол для интеграции UIKit контроллера в SwiftUI:
struct ScannerView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> ScannerViewController
func updateUIViewController(...)
func makeCoordinator() -> Coordinator
}Coordinator выступает делегатом для UIKit компонента и обновляет SwiftUI состояние.
AVCaptureDevice- доступ к камереAVCaptureMetadataOutput- распознавание кодов (EAN-8, EAN-13)metadataObjectTypes- список поддерживаемых форматов
Изменения @Published свойств всегда в main thread через DispatchQueue.main.async.
- Визуальная рамка области сканирования с анимацией
- Кнопка "Scan Again" для повторного сканирования
- Поддержка QR-кодов и других форматов (Code 128, PDF417)
- История отсканированных кодов с возможностью копирования
- Haptic feedback при успешном сканировании
- Проверка разрешений камеры с UI для настроек
- Фонарик для сканирования в темноте
- Поделиться баркодом (share sheet)
- Unit тесты для ViewModel
- Локализация (EN/RU)
Проект создан на основе обучающего туториала от Sean Allen. Материал был адаптирован и дополнен для изучения интеграции SwiftUI и UIKit, работы с AVFoundation и архитектурных паттернов.
Happy Scanning! 📲