Привет!
Хочу поделиться с сообществом информацией о простом, и, главное внедренном в операционную систему (7.0+) возможностью распознания шрих-кодов, QR-кодов, и даже Aztec-кодов.
Как мне показалось, далеко не все в курсе этой возможности, и, надеюсь, эта информация будет для вас полезной.
Пример реализован на Swift.
1. Создадим проект

2. Добавим в storyboard, на наш единственный view controller вьюшку — обычный UIView

3. Слинкуем наш UIView с @IBOutlet cameraView в ViewController.swift
4. Бросим туда же UILabel (слинкуем с resultLabel)
5. Добавим UIButton (слинкуем с startStopButton)
6. Добавим «действие» (action) кнопки — startStopButtonTouchUpInside
7. Для полноты счастья я добавил звучок в приложение, и его проигрываение при успешном считывании
8. Не забудем добавить AVFoundation в список Frameworks
9. Отключим переориентацию устройства, сейчас пока не об этом:

Ниже приведен текст ViewController.swift:
Надеюсь эта информация вам помогла (или поможет в будующем).
Ссылка на GitHub этого примера.
Удачи!
Хочу поделиться с сообществом информацией о простом, и, главное внедренном в операционную систему (7.0+) возможностью распознания шрих-кодов, QR-кодов, и даже Aztec-кодов.
Как мне показалось, далеко не все в курсе этой возможности, и, надеюсь, эта информация будет для вас полезной.
Пример реализован на Swift.
1. Создадим проект

2. Добавим в storyboard, на наш единственный view controller вьюшку — обычный UIView

3. Слинкуем наш UIView с @IBOutlet cameraView в ViewController.swift
4. Бросим туда же UILabel (слинкуем с resultLabel)
5. Добавим UIButton (слинкуем с startStopButton)
6. Добавим «действие» (action) кнопки — startStopButtonTouchUpInside
7. Для полноты счастья я добавил звучок в приложение, и его проигрываение при успешном считывании
8. Не забудем добавить AVFoundation в список Frameworks
9. Отключим переориентацию устройства, сейчас пока не об этом:

Ниже приведен текст ViewController.swift:
import UIKit
import AVFoundation
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
@IBOutlet weak var startStopButton: UIButton!
@IBOutlet weak var cameraView: UIView!
@IBOutlet weak var resultLabel: UILabel!
var captureSession: AVCaptureSession? // наша сессия для захвата видео с камеры
var videoPreviewLayer: AVCaptureVideoPreviewLayer? // слой для отображения видео с камеры
var audioPlayer: AVAudioPlayer? // будем щелкать звуком "затвора" при обнаружении кода
var isActive: Bool = false // признак того, что мы сейчас в режиме поиска кода
// старт-стоп распознования
@IBAction func startStopButtonTouchUpInside(sender: AnyObject) {
if isActive {
stopRec()
} else {
startRec()
}
}
// это можно сделать и в другом месте, но я решил тут
override func viewDidLoad() {
super.viewDidLoad()
// пытаемся загрузить файл со звуком
let path = NSBundle.mainBundle().pathForResource("chpok", ofType: "mp3")
if path == nil {
println("Файл со звуком не найден")
return
}
let url = NSURL(string: path!)
var error: NSError?
audioPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
if error != nil || audioPlayer == nil {
println("что-то со звуком не так")
if error != nil {
println(error!.description);
}
return
}
// ура!
audioPlayer!.prepareToPlay()
}
func startRec() -> Bool {
if isActive {
return true
}
var error: NSError?
let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
let input = AVCaptureDeviceInput.deviceInputWithDevice(captureDevice, error: &error) as? AVCaptureDeviceInput
if input == nil {
// по каким-то причинам мы не имеем доступ к камере, выходим
if error != nil {
println(error!.description)
}
return false
}
// меняем текст кнопки
startStopButton.setTitle("Закончить", forState: .Normal)
// настраиваем перехват и анализ видеопотока
// перехват
captureSession = AVCaptureSession()
captureSession!.addInput(input)
let dispatchQueue = dispatch_queue_create("barCodeQueue", nil)
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession!.addOutput(captureMetadataOutput)
captureMetadataOutput.setMetadataObjectsDelegate(self, queue:dispatchQueue)
// тут я перечислил все виды бар-куар-кодов, которые поддерживаются на текущий момент
captureMetadataOutput.metadataObjectTypes = [
AVMetadataObjectTypeQRCode,
AVMetadataObjectTypeUPCECode,
AVMetadataObjectTypeCode39Code,
AVMetadataObjectTypeCode39Mod43Code,
AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeCode93Code,
AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypePDF417Code,
AVMetadataObjectTypeAztecCode
]
// ну и добавляем стрим с камеры, чтобы пользователь видел что он снимает
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
videoPreviewLayer!.videoGravity = AVLayerVideoGravityResizeAspectFill
videoPreviewLayer!.frame = cameraView.layer.bounds
cameraView.layer.addSublayer(videoPreviewLayer)
// show must go on!
captureSession!.startRunning()
// ок, мы готовы
isActive = true
return true
}
func stopRec() -> Bool {
// ну тут все очень просто:
if !isActive {
return true
}
// меняем текст кнопки
startStopButton.setTitle("Начать", forState: .Normal)
// прекращаем съемку
captureSession!.stopRunning()
captureSession = nil;
// убираем стрим с камеры
videoPreviewLayer!.removeFromSuperlayer()
// меняем текст
resultLabel.text = "Наведите камеру"
// ок, мы завершили
isActive = false
return true
}
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
if metadataObjects != nil && metadataObjects.count > 0 {
let metadataObj = metadataObjects[0] as AVMetadataMachineReadableCodeObject
// меняем текст надписи в основном потоке
dispatch_async(dispatch_get_main_queue()) {
self.resultLabel.text = metadataObj.stringValue
}
audioPlayer?.play()
}
}
}
Надеюсь эта информация вам помогла (или поможет в будующем).
Ссылка на GitHub этого примера.
Удачи!