Понимание AVFoundation для сканирования штрих-кода и QR-кода

Рамка AVFoundation от Apple обеспечивает полнофункциональный низкоуровневый интерфейс для работы с аудиовизуальными носителями на устройствах iOS. Для сканирования штрих-кода и QR-кода фреймворк выставляет класс , который может обнаруживать широкий спектр машиночитаемых кодов в реальном времени из корма камеры. Это включает QR-коды, EAN-8/13, Code 128, PDF417, Aztec и многие другие форматы. Фреймворк обрабатывает тяжелую работу по анализу изображений и декодированию кода, позволяя разработчикам сосредоточиться на логике приложений, а не на реализации пользовательских алгоритмов сканирования.

Сканирование AVFoundation аппаратно ускоряется на современных устройствах, предлагая быстрое и надежное обнаружение даже в сложных условиях освещения. Он работает как с передней, так и с задней камерами, и область обнаружения может быть ограничена конкретной областью, представляющей интерес, для повышения производительности и пользовательского опыта.

Настройка сеанса захвата камеры

Ядром любого сканера на основе AVFoundation является . Этот объект организует поток данных от ввода камеры до вывода метаданных. Настройка сеанса требует нескольких этапов шаблона, которые лучше всего реализовать в специальном контроллере просмотра или классе менеджера.

Запросить разрешение камеры

Перед доступом к камере вы должны запросить разрешение пользователя. Начиная с iOS 10, вам нужно включить ключ в файл Info.plist со строкой, объясняющей, почему вашему приложению нужна камера. Разрешение запрашивается с использованием . Обработайте оба случая - предоставленные и отклоненные - и обновите свой пользовательский интерфейс соответственно.

AVCaptureDevice.requestAccess(for: .video) { granted in
 if granted {
 // Configure and start the capture session
 } else {
 // Show an alert guiding the user to Settings
 }
}

Создание AVCaptureSession

После получения разрешения, настройте предустановленную сессию для управления качеством видео; для сканирования штрих-кода является хорошим по умолчанию, но вы также можете использовать для более быстрой обработки.

let session = AVCaptureSession()
session.sessionPreset = .high

Добавление входной камеры

Получите видеоустройство по умолчанию (заднюю камеру) и создайте . Если вход не может быть добавлен к сеансу (например, устройство занято), уловите ошибку и представьте обратную связь пользователю.

guard let camera = AVCaptureDevice.default(for: .video) else { return }
do {
 let input = try AVCaptureDeviceInput(device: camera)
 guard session.canAddInput(input) else { return }
 session.addInput(input)
} catch {
 print("Camera input error: \(error.localizedDescription)")
}

Добавление выходных метаданных

Создайте экземпляр , установите его делегата (на выделенную последовательную очередь) и добавьте его в сессию. Делегат получит обнаруженные объекты метаданных.

let metadataOutput = AVCaptureMetadataOutput()
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
guard session.canAddOutput(metadataOutput) else { return }
session.addOutput(metadataOutput)

// Specify which code types to detect – must be done after the output is added
metadataOutput.metadataObjectTypes = [.qr, .ean13, .code128, .pdf417]

Важно: должен быть установлен после добавления вывода к сессии. Установка его раньше вызовет сбой.

Начало сессии

Запустите сеанс на фоновой нити, чтобы поддерживать отзывчивость пользовательского интерфейса. Позвоните в фоновой очереди отправки или в выделенной последовательной очереди.

DispatchQueue.global(qos: .userInitiated).async {
 session.startRunning()
}

Реализация метода делегирования

Метод делегата называется всякий раз, когда сканер обнаруживает один или несколько кодов. Этот метод получает массив экземпляров , которые вам нужно отлить для доступа к декодированной строке.

func metadataOutput(_ output: AVCaptureMetadataOutput,
 didOutput metadataObjects: [AVMetadataObject],
 from connection: AVCaptureConnection) {
 // Process only the first detected code (most common pattern)
 guard let metadataObject = metadataObjects.first,
 let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject,
 let stringValue = readableObject.stringValue else { return }

 // Use the scanned value (e.g., display, validate, or send to server)
 handleScannedCode(stringValue, type: readableObject.type)
}

Обычно после успешного сканирования сеанс прекращают, чтобы предотвратить повторные обнаружения.Позвоните после обработки кода и перезапустите его, когда пользователь сбросит сканер.

Обработка обнаруженных кодов

После того, как у вас есть значение строки, определите, какие действия предпринять на основе типа кода и контента.

  • URLs — Открыть в Safari или браузере внутри приложения с использованием .
  • Wi-Fi учетные данные — Просмотрите стандартный формат и подключитесь программно (требует дополнительного права).
  • Коды продуктов — Просмотрите информацию о продукте через API, такую как UPC Database или свою собственную систему инвентаризации.
  • Контактная информация — форматы Parse vCard или MeCard и создание нового контакта в адресной книге.
  • Текст — Отображение в предупреждении или копия на доску.

Для каждого типа кода, валидируйте строку перед обработкой.Неправильные или вредоносные коды должны быть проигнорированы или сообщены изящно.

Лучшие практики для производительности сканирования

Чтобы обеспечить плавное и эффективное сканирование, следуйте этим рекомендациям:

  • Ограничить типы объектов метаданных — только включите форматы кода, которые действительно нужны вашему приложению.
  • Установите интересующую область — Используйте для определения небольшой части видеоканала, где ожидаются коды. Это значительно повышает скорость обнаружения и уменьшает ложные срабатывания.
  • Используйте правильную видеогравитацию — сохраняет пропорциональный предварительный просмотр камеры и идеально подходит для наложения направляющих сканирования.
  • Используйте последовательную очередь для обратного вызова делегатов — выполните тяжелую обработку (например, поиск по сети) из основного потока, чтобы поддерживать адаптивность пользовательского интерфейса.
  • Подумайте о поддержке факела — Позвольте пользователю переключать факел камеры для сценариев при слабом освещении. перед переключением.
  • Свернуть сканирование после обработки — После успешного сканирования перезагрузить сеанс с короткой задержкой (например, 1–2 секунды) для предотвращения немедленного повторного обнаружения того же кода.

Предоставление обратной связи пользователя

Хороший опыт сканирования включает визуальные и слуховые сигналы. Внедрите эти механизмы обратной связи, чтобы направлять пользователя:

  • Визуальное наложение — Нарисуйте прямоугольник выделения вокруг обнаруженного кода с использованием свойств . Для этого требуется преобразование координат метаданных для просмотра координат через .
  • Анимация — Играйте в тонкую анимацию (например, сокращающуюся границу), когда код распознается.
  • Звук — воспроизводить системный звук с использованием с коротким, положительным тоном, как (звук «Почта отправлена»).
  • Гаптическая обратная связь — Используйте или для тонкой вибрации.
  • Руководство по области сканирования — Отображение полупрозрачного прямоугольника с угловыми руководствами, чтобы помочь пользователям центрировать код.

Обработка ошибок и Edge Cases

Надежная обработка ошибок гарантирует, что ваш сканер изящно ухудшается, когда что-то идет не так.

  • Камера недоступна — Проверьте и на устройстве.На iPod touch или симуляторе без камеры представьте осмысленное сообщение.
  • Разрешение отказано — Покажите оповещение кнопкой, которая открывает Настройки через .
  • Сбой конфигурации сессии — ошибки в логике, когда или возвращается . Это может произойти, если другое приложение использует камеру в фоновом режиме (редко).
  • Низкое освещение или размытые изображения — уменьшают область обнаружения, представляющую интерес, и обеспечивают автофокусировку камеры.
  • Недействительные или неподдерживаемые типы кода — свойство может поддерживать не все форматы на всех устройствах. Используйте для запроса совместимости перед установкой.

Тестирование через устройства

Производительность сканирования штрих-кода AVFoundation значительно варьируется в зависимости от поколений iPhone и iPad.

  • Старые устройства (iPhone 6s, iPad Air 2) — имеют более медленные процессоры и могут бороться с предустановками с высоким разрешением. Используйте для оптимального баланса на старом оборудовании.
  • Устройства с различной оптикой камеры — iPhone с телефото или ультраширокими камерами могут фокусироваться по-разному. Всегда используйте широкоугольную камеру по умолчанию для сканирования штрих-кода.
  • Среды с низким освещением - тест в тусклых условиях, чтобы обеспечить видимость наложения сканирования и работу переключения факела.
  • Различные размеры и ориентации кода - попробуйте коды от наклеек размером 1 см × 1 см до больших плакатов и проверьте ландшафт против портретного сканирования.

Передовые соображения

Для производственных приложений рассмотрите возможность добавления таких функций, как непрерывное сканирование (разрешение нескольких кодов за один сеанс), управление масштабированием или интеграция с ARKit для наложений дополненной реальности. Если вам нужно обрабатывать коды из неподвижных изображений (например, фотобиблиотека), используйте или из фреймворка Vision, хотя AVFoundation, как правило, быстрее для видео в реальном времени.

Для более глубокого погружения в конфигурацию AVFoundation обратитесь к руководству Apple Setting Up a Capture Session и документации AVCaptureMetadataOutput . Вы также можете найти полный образец проекта в Scanning Barcodes с помощью AVCaptureMetadataOutput .

Следуя этим рекомендациям и тщательно проверяя вашу реализацию, вы можете предоставить отполированный высокопроизводительный сканер штрих-кода и QR-кода, который повышает удобство использования и надежность вашего приложения iOS.