Як я можу сканувати штрих-коди на iOS?


189

Як я можу просто сканувати штрих-коди на iPhone та / або iPad?


7
На жаль, камера iPhone в даний час жахлива для зчитування штрих-кодів, оскільки її об'єктив фіксується на ∞. Вдало хоч!
Аластер Стюарт

1
Тільки що вирішили цю проблему, так і напишу мої спостереження. Я перевірив кілька варіантів. RSBarcodes_Swift - легко було інтегруватися, але мав дуже низьку продуктивність. ZBarSDK - це також було легко здійснити, altho взяв декілька пошуків Google, щоб знайти як. Але мав дійсно гарну продуктивність (не сканував datamatrix та інші рідкісні коди) справді добре працює для штрих-кодів / QRCode. Але Скандіт був найкращим з усіх. Супершвидкий, сканує все. на жаль коштує досить багато.
Katafalkas

Відповіді:


82

Ми створили додаток "Штрих-коди" для iPhone. Він може декодувати QR-коди. Вихідний код доступний у проекті zxing ; конкретно, ви хочете подивитися на клієнт iPhone та частковий порт C ++ основної бібліотеки . Порт трохи старий, починаючи з 0,9 випуску коду Java, але все одно повинен працювати досить добре.

Якщо вам потрібно сканувати інші формати, наприклад формати 1D, ви можете продовжити порт коду Java в рамках цього проекту на C ++.

EDIT: Штрих-коди та iphoneкод у проекті були скасовані на початку 2014 року.


Шон, яку саме ліцензію використовує. Я хочу створити платний додаток, який використовує Zbar. Це можливо за ліцензійною угодою?
Раду

1
Щоб було зрозуміло, на даний момент ZXing на iPhone підтримує лише QR-коди?
RefuX

Я вважаю, що більше було перенесено на C ++, але порт, як і раніше, є грубим і застарілим відлунням коду Java. Отже, так більше підтримується, хоча, можливо, не дуже добре.
Шон Оуен

ZXing для iPhone все ще протікає в пам'яті на 1,7 вер.
Йоон Лі

Зі списку проблем на git zXing я розумію, що ми можемо сканувати штрих-код лише в альбомному режимі.
Саґріан

81

Перевірте, ZBar читає QR-код та коди ECN / ISBN і доступний як за ліцензією LGPL v2.


5
Частково правильно. ZBar.app ліцензується за ліцензією Apache (версія 2.0), проте бібліотека ліцензується під LGPL v2.
Шон

3
До жаль , ліцензія вимагає , щоб обмінюватися файлами об'єктів свого застосування з тими , хто просить їх .. перевірити zbar.sourceforge.net/iphone/sdkdoc/licensing.html
Бен Клейтон

1
@BenClayton, що означає обмін файлами об’єктів програми?
Dejell

@Odelya Надсилання файлів .o, генерованих Xcode будь-кому, теоретично дозволяє їм створити ваш додаток. Я точно не радий це робити (особливо для моїх клієнтів), тому ZBar не викликає сумнівів для нас. Сторінка ліцензування ZBar пропонує вам просто "сподіватися, що ніхто їх не вимагає!"
Бен Клейтон

@BenClayton A. Дякую Б. Я міг би змінити компонент, якщо хтось запитає та вимагатиме вже завантажених користувачів додатків, щоб завантажити нову версію. Чи достатньо? C. Отже, яку бібліотеку ви використовуєте?
Dejell

56

Як і у випадку випуску, iOS7вам більше не потрібно використовувати зовнішню рамку чи бібліотеку. Екосистема iOS з AVFoundation тепер повністю підтримує сканування майже кожного коду від QR через EAN до UPC.

Просто подивіться технічну записку та посібник із програмування AVFoundation. AVMetadataObjectTypeQRCodeтвій друг.

Ось приємний підручник, який показує його покроково: Бібліотека сканування QR-коду iOS7

Лише невеликий приклад того, як його налаштувати:

#pragma mark -
#pragma mark AVFoundationScanSetup

- (void) setupScanner;
{
    self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];

    self.session = [[AVCaptureSession alloc] init];

    self.output = [[AVCaptureMetadataOutput alloc] init];
    [self.session addOutput:self.output];
    [self.session addInput:self.input];

    [self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    self.output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];

    self.preview = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
    self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
    self.preview.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);

    AVCaptureConnection *con = self.preview.connection;

    con.videoOrientation = AVCaptureVideoOrientationLandscapeLeft;

    [self.view.layer insertSublayer:self.preview atIndex:0];
}

1
Якщо ви хочете виявити штрих-код із зображення на iOS8, цей підручник може бути корисним.
NSDeveloper

Я виявив, що мені довелося зателефонувати startRunningна сеанс, щоб отримати вищезгаданий код для роботи, якщо хтось допомагає :)
Кріс,

13

Камера iPhone 4 - це більше, ніж можливість робити штрих-коди. Бібліотека штрих-коду, що перетинає зебру, має вилку на github zxing-iphone . Це з відкритим кодом.


1
Здається, ваш пост означає, що цей порт ZXing може сканувати більше, ніж просто QRCodes? Це так?
RefuX

4
Начебто, вилка Github
Джош Браун


10

Є дві основні бібліотеки:

  • ZXing бібліотека, написана на Java, а потім перенесена в Objective C / C ++ (лише QR-код). І інший порт для ObjC зробив TheLevelUp: ZXingObjC

  • ZBar - програмне забезпечення з відкритим кодом для читання штрих-кодів на основі С.

Згідно з моїми експериментами, ZBar набагато точніший і швидший, ніж ZXing, принаймні на iPhone.


Мені здається, що ZXingObjC - це той, кого до цього часу слід висувати наверх, набравши найбільше голосів. Я його ще не використовував , але в описі йдеться про те, що він відповідає парі ZXing 2.0.
Шаоло

Ліцензія ZBar вимагає запропонувати користувачам об'єктні файли, щоб вони могли запускати їх, а також можуть змінювати свою бібліотеку.
Dejell

Рекомендую ZXingObjC
Dejell


7

Ви можете знайти ще одне нативне рішення для iOS, використовуючи Swift 4 та Xcode 9 нижче. Рідні AVFoundationрамки, використовувані в цьому рішенні.

Перша частина - це підклас, для UIViewControllerякого є пов'язані функції настройки та обробника AVCaptureSession.

import UIKit
import AVFoundation

class BarCodeScannerViewController: UIViewController {

    let captureSession = AVCaptureSession()
    var videoPreviewLayer: AVCaptureVideoPreviewLayer!
    var initialized = false

    let barCodeTypes = [AVMetadataObject.ObjectType.upce,
                        AVMetadataObject.ObjectType.code39,
                        AVMetadataObject.ObjectType.code39Mod43,
                        AVMetadataObject.ObjectType.code93,
                        AVMetadataObject.ObjectType.code128,
                        AVMetadataObject.ObjectType.ean8,
                        AVMetadataObject.ObjectType.ean13,
                        AVMetadataObject.ObjectType.aztec,
                        AVMetadataObject.ObjectType.pdf417,
                        AVMetadataObject.ObjectType.itf14,
                        AVMetadataObject.ObjectType.dataMatrix,
                        AVMetadataObject.ObjectType.interleaved2of5,
                        AVMetadataObject.ObjectType.qr]

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        setupCapture()
        // set observer for UIApplicationWillEnterForeground, so we know when to start the capture session again
        NotificationCenter.default.addObserver(self,
                                           selector: #selector(willEnterForeground),
                                           name: .UIApplicationWillEnterForeground,
                                           object: nil)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // this view is no longer topmost in the app, so we don't need a callback if we return to the app.
        NotificationCenter.default.removeObserver(self,
                                              name: .UIApplicationWillEnterForeground,
                                              object: nil)
    }

    // This is called when we return from another app to the scanner view
    @objc func willEnterForeground() {
        setupCapture()
    }

    func setupCapture() {
        var success = false
        var accessDenied = false
        var accessRequested = false

        let authorizationStatus = AVCaptureDevice.authorizationStatus(for: .video)
        if authorizationStatus == .notDetermined {
            // permission dialog not yet presented, request authorization
            accessRequested = true
            AVCaptureDevice.requestAccess(for: .video,
                                      completionHandler: { (granted:Bool) -> Void in
                                          self.setupCapture();
            })
            return
        }
        if authorizationStatus == .restricted || authorizationStatus == .denied {
            accessDenied = true
        }
        if initialized {
            success = true
        } else {
            let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera,
                                                                                        .builtInTelephotoCamera,
                                                                                        .builtInDualCamera],
                                                                          mediaType: .video,
                                                                          position: .unspecified)

            if let captureDevice = deviceDiscoverySession.devices.first {
                do {
                    let videoInput = try AVCaptureDeviceInput(device: captureDevice)
                    captureSession.addInput(videoInput)
                    success = true
                } catch {
                    NSLog("Cannot construct capture device input")
                }
            } else {
                NSLog("Cannot get capture device")
            }
        }
        if success {
            DispatchQueue.global().async {
                self.captureSession.startRunning()
                DispatchQueue.main.async {
                    let captureMetadataOutput = AVCaptureMetadataOutput()
                    self.captureSession.addOutput(captureMetadataOutput)
                    let newSerialQueue = DispatchQueue(label: "barCodeScannerQueue") // in iOS 11 you can use main queue
                    captureMetadataOutput.setMetadataObjectsDelegate(self, queue: newSerialQueue)
                    captureMetadataOutput.metadataObjectTypes = self.barCodeTypes
                    self.videoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
                    self.videoPreviewLayer.videoGravity = .resizeAspectFill
                    self.videoPreviewLayer.frame = self.view.layer.bounds
                    self.view.layer.addSublayer(self.videoPreviewLayer)
                } 
            }
            initialized = true
        } else {
            // Only show a dialog if we have not just asked the user for permission to use the camera.  Asking permission
            // sends its own dialog to th user
            if !accessRequested {
                // Generic message if we cannot figure out why we cannot establish a camera session
                var message = "Cannot access camera to scan bar codes"
                #if (arch(i386) || arch(x86_64)) && (!os(macOS))
                    message = "You are running on the simulator, which does not hae a camera device.  Try this on a real iOS device."
                #endif
                if accessDenied {
                    message = "You have denied this app permission to access to the camera.  Please go to settings and enable camera access permission to be able to scan bar codes"
                }
                let alertPrompt = UIAlertController(title: "Cannot access camera", message: message, preferredStyle: .alert)
                let confirmAction = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
                    self.navigationController?.popViewController(animated: true)
                })
                alertPrompt.addAction(confirmAction)
                self.present(alertPrompt, animated: true, completion: nil)
            }
        }
    }

    func handleCapturedOutput(metadataObjects: [AVMetadataObject]) {
        if metadataObjects.count == 0 {
            return
        }

        guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject else {
            return
        }

        if barCodeTypes.contains(metadataObject.type) {
            if let metaDataString = metadataObject.stringValue {
                captureSession.stopRunning()
                displayResult(code: metaDataString)
                return
            }
        }
    }

    func displayResult(code: String) {
        let alertPrompt = UIAlertController(title: "Bar code detected", message: code, preferredStyle: .alert)
        if let url = URL(string: code) {
            let confirmAction = UIAlertAction(title: "Launch URL", style: .default, handler: { (action) -> Void in
                UIApplication.shared.open(url, options: [:], completionHandler: { (result) in
                    if result {
                        NSLog("opened url")
                    } else {
                        let alertPrompt = UIAlertController(title: "Cannot open url", message: nil, preferredStyle: .alert)
                        let confirmAction = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
                        })
                        alertPrompt.addAction(confirmAction)
                        self.present(alertPrompt, animated: true, completion: {
                            self.setupCapture()
                        })
                    }
                })        
            })
            alertPrompt.addAction(confirmAction)
        }
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: { (action) -> Void in
            self.setupCapture()
        })
        alertPrompt.addAction(cancelAction)
        present(alertPrompt, animated: true, completion: nil)
    }

}

Друга частина - це розширення нашого UIViewControllerпідкласу, AVCaptureMetadataOutputObjectsDelegateде ми отримуємо відзняті результати.

extension BarCodeScannerViewController: AVCaptureMetadataOutputObjectsDelegate {

    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        handleCapturedOutput(metadataObjects: metadataObjects)
    }

}

Оновлення для Swift 4.2

.UIApplicationWillEnterForegroundзміни як UIApplication.willEnterForegroundNotification.


це дасть назву продукту, розмір, ціну, URL-адресу товару, валюту, назву магазину? або він дасть лише номер штрих-коду @abdullahselek
Р. Мохан

@ R.Mohan це пов'язано з прочитаним штрих-кодом. Перевірте AVCaptureMetadataOutput та AVMetadataMachineReadableCodeObject і спробуйте прочитати metadataObjectsвсередині функціїCCPuredOutput .
abdullahselek

Гаразд, спробую це. Дякую за відповідь @abdullahselek
Р. Мохан

5

Не впевнений, чи це допоможе, але ось посилання на бібліотеку QR-коду з відкритим кодом . Як бачите, пара людей вже використовувала це для створення додатків для iphone.

У Вікіпедії є стаття, яка пояснює, що таке QR-коди . На мою думку, QR-коди набагато більше підходять за призначенням, ніж стандартний штрих-код, що стосується iphone, оскільки він був розроблений для такого типу реалізації.


5

Якщо підтримка iPad 2 або iPod Touch важлива для вашої програми, я вибрав би SDK-сканер штрих-коду, який може декодувати штрих-коди в розмитих зображеннях, таких як сканер штрих-коду Scandit SDK для iOS та Android. Розшифровка розмитих зображень штрих-коду також корисна на телефонах із камерами автофокусування, оскільки користувачеві не потрібно чекати, коли автофокус почне працювати.

Scandit має безкоштовний ціновий план спільноти, а також має API продукту, що дозволяє легко перетворювати номери штрих-кодів у назви продуктів.

(Відмова: Я є співзасновником Scandit)


4

Який ваш досвід роботи з цим додатком? Для мене потрібне 10s або більше для декодування простого штрих-коду datamatrix!
iamj4de

1
Посилання змінено на stefan.hafeneger.name/blog/2009/09/08/…
Суреш Варма

1
Пряме посилання (не думаю, що Google це зникне на деякий час) code.google.com/p/barcodeapp

хтось знає, як називається офіційна назва програми Стефана в додатку? Я хотів би завантажити його перед тим, як зануритися у фактичний код.
макутан

3

Проблема iPhone-камери полягає в тому, що перші моделі (яких у продажу є багато тонн) мають камеру з фіксованим фокусом, яка не може робити знімки у фокусі на відстані менше 2 футів. Зображення розмиті та спотворені, і якщо брати з більшої відстані, недостатньо деталей / інформації зі штрих-коду.

Кілька компаній розробили додатки для iPhone, які допоможуть досягти цього за допомогою передових технологій усунення розмитості. Ті програми, які ви можете знайти в магазині додатків Apple: pic2shop, RedLaser та ShopSavvy. Усі компанії оголосили, що у них є також SDK - деякі на безкоштовних або дуже пільгових умовах, перевірте це.


Я намагався використовувати ShopSavvy з 3G iphone. Це забавно, але виходить з ладу дуже часто, і він дуже важко читає дуже чіткі, плоскі штрих-коди.
Джеймс Мур

1
І я просто спробував pic2shop. Цитата мого нареченого: "Це повинно полегшити наше життя ЯК?" Це милий додаток, але насправді він не в змозі прочитати штрих-код, наскільки я можу сказати.
Джеймс Мур

Який формат ви намагалися прочитати? Я намагався використовувати pic2shop для сканування EAN, і він працює дуже добре. Плата за ліцензію коштує дорого, навіть більше, ніж RedLaser.
iamj4de

2

З Swift 5 це просто і супер швидко !!

Вам просто потрібно додати какао-стручки "BarcodeScanner", ось повний код

source 'https://github.com/CocoaPods/Specs.git' 
platform :ios, '12.0' 
target 'Simple BarcodeScanner' 
do   
pod 'BarcodeScanner' 
end

Обов’язково додайте дозвіл камери у свій .plist файл

<key>NSCameraUsageDescription</key>
<string>Camera usage description</string>

Таким чином додайте сканер і обробляйте результат у своєму ViewController

import UIKit
import BarcodeScanner

class ViewController: UIViewController, BarcodeScannerCodeDelegate, BarcodeScannerErrorDelegate, BarcodeScannerDismissalDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let viewController = BarcodeScannerViewController()
        viewController.codeDelegate = self
        viewController.errorDelegate = self
        viewController.dismissalDelegate = self

        present(viewController, animated: true, completion: nil)
    }

    func scanner(_ controller: BarcodeScannerViewController, didCaptureCode code: String, type: String) {
        print("Product's Bar code is :", code)
        controller.dismiss(animated: true, completion: nil)
    }

    func scanner(_ controller: BarcodeScannerViewController, didReceiveError error: Error) {
        print(error)
    }

    func scannerDidDismiss(_ controller: BarcodeScannerViewController) {
        controller.dismiss(animated: true, completion: nil)
    }
}

І все-таки будь-яке питання чи проблеми, будь ласка, ознайомтесь із зразком заявки тут із повним вихідним кодом



1

Я вважаю, що це можна зробити за допомогою AVFramework, ось зразок коду для цього

import UIKit
import AVFoundation

class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate
{

    @IBOutlet weak var lblQRCodeResult: UILabel!
    @IBOutlet weak var lblQRCodeLabel: UILabel!

    var objCaptureSession:AVCaptureSession?
    var objCaptureVideoPreviewLayer:AVCaptureVideoPreviewLayer?
    var vwQRCode:UIView?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.configureVideoCapture()
        self.addVideoPreviewLayer()
        self.initializeQRView()
    }

    func configureVideoCapture() {
        let objCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        var error:NSError?
        let objCaptureDeviceInput: AnyObject!
        do {
            objCaptureDeviceInput = try AVCaptureDeviceInput(device: objCaptureDevice) as AVCaptureDeviceInput

        } catch let error1 as NSError {
            error = error1
            objCaptureDeviceInput = nil
        }
        objCaptureSession = AVCaptureSession()
        objCaptureSession?.addInput(objCaptureDeviceInput as! AVCaptureInput)
        let objCaptureMetadataOutput = AVCaptureMetadataOutput()
        objCaptureSession?.addOutput(objCaptureMetadataOutput)
        objCaptureMetadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        objCaptureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
    }

    func addVideoPreviewLayer() {
        objCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: objCaptureSession)
        objCaptureVideoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
        objCaptureVideoPreviewLayer?.frame = view.layer.bounds
        self.view.layer.addSublayer(objCaptureVideoPreviewLayer!)
        objCaptureSession?.startRunning()
        self.view.bringSubviewToFront(lblQRCodeResult)
        self.view.bringSubviewToFront(lblQRCodeLabel)
    }

    func initializeQRView() {
        vwQRCode = UIView()
        vwQRCode?.layer.borderColor = UIColor.redColor().CGColor
        vwQRCode?.layer.borderWidth = 5
        self.view.addSubview(vwQRCode!)
        self.view.bringSubviewToFront(vwQRCode!)
    }

    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        if metadataObjects == nil || metadataObjects.count == 0 {
            vwQRCode?.frame = CGRectZero
            lblQRCodeResult.text = "QR Code wans't found"
            return
        }
        let objMetadataMachineReadableCodeObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
        if objMetadataMachineReadableCodeObject.type == AVMetadataObjectTypeQRCode {
            let objBarCode = objCaptureVideoPreviewLayer?.transformedMetadataObjectForMetadataObject(objMetadataMachineReadableCodeObject as AVMetadataMachineReadableCodeObject) as! AVMetadataMachineReadableCodeObject
            vwQRCode?.frame = objBarCode.bounds;
            if objMetadataMachineReadableCodeObject.stringValue != nil {
                lblQRCodeResult.text = objMetadataMachineReadableCodeObject.stringValue
            }
        }
    }
}

1

Ось простий код:

func scanbarcode()
{
    view.backgroundColor = UIColor.blackColor()
    captureSession = AVCaptureSession()

    let videoCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    let videoInput: AVCaptureDeviceInput

    do {
        videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
    } catch {
        return
    }

    if (captureSession.canAddInput(videoInput)) {
        captureSession.addInput(videoInput)
    } else {
        failed();
        return;
    }

    let metadataOutput = AVCaptureMetadataOutput()

    if (captureSession.canAddOutput(metadataOutput)) {
        captureSession.addOutput(metadataOutput)

        metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypePDF417Code]
    } else {
        failed()
        return
    }

    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession);
    previewLayer.frame = view.layer.bounds;
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    view.layer.addSublayer(previewLayer);
    view.addSubview(closeBtn)
    view.addSubview(backimg)

    captureSession.startRunning();

}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func failed() {
    let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .Alert)
    ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
    presentViewController(ac, animated: true, completion: nil)
    captureSession = nil
}

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    if (captureSession?.running == false) {
        captureSession.startRunning();
    }
}

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)

    if (captureSession?.running == true) {
        captureSession.stopRunning();
    }
}

func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
    captureSession.stopRunning()

    if let metadataObject = metadataObjects.first {
        let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject;

        AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
        foundCode(readableObject.stringValue);
    }

   // dismissViewControllerAnimated(true, completion: nil)
}

func foundCode(code: String) {
    var createAccountErrorAlert: UIAlertView = UIAlertView()
    createAccountErrorAlert.delegate = self
    createAccountErrorAlert.title = "Alert"
    createAccountErrorAlert.message = code
    createAccountErrorAlert.addButtonWithTitle("ok")
    createAccountErrorAlert.addButtonWithTitle("Retry")
    createAccountErrorAlert.show()
    NSUserDefaults.standardUserDefaults().setObject(code, forKey: "barcode")
    NSUserDefaults.standardUserDefaults().synchronize()
    ItemBarcode = code
    print(code)
}

override func prefersStatusBarHidden() -> Bool {
    return true
}

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return .Portrait
}

1

Якщо ви розробляєте для iOS> 10.2 за допомогою Swift 4, тоді ви можете спробувати моє рішення. Я змішав це і це підручник і придумав ViewController, який сканує QR-код і print()його. У мене також є перемикач у своєму інтерфейсі, щоб увімкнути світло камери. Поки що я тестував його лише на iPhone SE, будь ласка, повідомте мене, якщо він не працює на нових iPhone.

Ось вам:

import UIKit
import AVFoundation

class QRCodeScanner: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

    let captureSession: AVCaptureSession = AVCaptureSession()
    var videoPreviewLayer: AVCaptureVideoPreviewLayer?
    let qrCodeFrameView: UIView = UIView()
    var captureDevice: AVCaptureDevice?

    override func viewDidLoad() {
        // Get the back-facing camera for capturing videos
        let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera, .builtInDualCamera], mediaType: AVMediaType.video, position: .back)

        captureDevice = deviceDiscoverySession.devices.first
        if captureDevice == nil {
            print("Failed to get the camera device")
            return
        }

        do {
            // Get an instance of the AVCaptureDeviceInput class using the previous device object.
            let input = try AVCaptureDeviceInput(device: captureDevice!)

            // Set the input device on the capture session.
            captureSession.addInput(input)

            // Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
            let captureMetadataOutput = AVCaptureMetadataOutput()
            captureSession.addOutput(captureMetadataOutput)

            // Set delegate and use the default dispatch queue to execute the call back
            captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            captureMetadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]

            // Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.

            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

            if let videoPreviewLayer = videoPreviewLayer {
                videoPreviewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
                videoPreviewLayer.frame = view.layer.bounds
                view.layer.addSublayer(videoPreviewLayer)

                // Start video capture.
                captureSession.startRunning()

                if let hasFlash = captureDevice?.hasFlash, let hasTorch = captureDevice?.hasTorch {
                    if hasFlash && hasTorch {
                        view.bringSubview(toFront: bottomBar)
                        try captureDevice?.lockForConfiguration()
                    }
                }
            }

            // QR Code Overlay
            qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
            qrCodeFrameView.layer.borderWidth = 2
            view.addSubview(qrCodeFrameView)
            view.bringSubview(toFront: qrCodeFrameView)

        } catch {
            // If any error occurs, simply print it out and don't continue any more.
            print("Error: \(error)")
            return
        }
    }

    // MARK: Buttons and Switch

    @IBAction func switchFlashChanged(_ sender: UISwitch) {
        do {
            if sender.isOn {
                captureDevice?.torchMode = .on
            } else {
                captureDevice?.torchMode = .off
            }
        }
    }

    // MARK: AVCaptureMetadataOutputObjectsDelegate

    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {

        // Check if the metadataObjects array is not nil and it contains at least one object.
        if metadataObjects.count == 0 {
            qrCodeFrameView.frame = CGRect.zero
            return
        }

        // Get the metadata object.
        let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject

        if metadataObj.type == AVMetadataObject.ObjectType.qr {
            // If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
            let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
            qrCodeFrameView.frame = barCodeObject!.bounds

            print("QR Code: \(metadataObj.stringValue)")
        }
    }
}

0

Іноді це може бути корисно також для створення QR-кодів . Для цього є чудова бібліотека С, яка працює як шарм. Він називається libqrencode . Написати спеціальний вид для відображення QR-коду тоді не так вже й складно, і це можна зробити за допомогою базового розуміння QuartzCore.


чи знаєте ви з будь-якого підручника про те, як включити це до проекту iCOS xCode?
Джеймс

Ви б не хотіли поділитися тим, як ви створили подання за допомогою квартеру? буде великим
часовим переходом

Це правильно. Однак переконайтеся, що ви відповідаєте ліцензії на програмне забезпечення, з якою публікується бібліотека.
GorillaPatch

Це питання стосується визнання, а не покоління.
Мсьє,

0

ви можете перевірити ZBarSDK, щоб прочитати QR-код та коди ECN / ISBN, просто інтегрувати спробуйте наступний код.

- (void)scanBarcodeWithZBarScanner
  {
// ADD: present a barcode reader that scans from the camera feed
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;

ZBarImageScanner *scanner = reader.scanner;
// TODO: (optional) additional reader configuration here

// EXAMPLE: disable rarely used I2/5 to improve performance
 [scanner setSymbology: ZBAR_I25
               config: ZBAR_CFG_ENABLE
                   to: 0];

//Get the return value from controller
[reader setReturnBlock:^(BOOL value) {

}

і в didFinishPickingMediaWithInfo ми отримуємо значення штрих-коду.

    - (void) imagePickerController: (UIImagePickerController*) reader
   didFinishPickingMediaWithInfo: (NSDictionary*) info
   {
    // ADD: get the decode results
    id<NSFastEnumeration> results =
    [info objectForKey: ZBarReaderControllerResults];
    ZBarSymbol *symbol = nil;
    for(symbol in results)
    // EXAMPLE: just grab the first barcode
    break;

    // EXAMPLE: do something useful with the barcode data
    barcodeValue = symbol.data;

    // EXAMPLE: do something useful with the barcode image
    barcodeImage =   [info objectForKey:UIImagePickerControllerOriginalImage];
    [_barcodeIV setImage:barcodeImage];

    //set the values for to TextFields
    [self setBarcodeValue:YES];

    // ADD: dismiss the controller (NB dismiss from the *reader*!)
    [reader dismissViewControllerAnimated:YES completion:nil];
   }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.