使用未解析的标识符

时间:2016-11-14 16:47:18

标签: ios swift

我正在构建条形码扫描仪。操作很简单 扫描条形码, 如果扫描的条形码在我的firebase数据库中,则执行func updateProductInfo()如果条形码不在我的firebase数据库中,请执行func enterNewProduct()。 我现在遇到的一个问题是如何定义metadataObj,以便所有以及我稍后定义的任何其他函数都可以访问它。我试图在ScanController课程的正下方定义它,但我无法弄明白。我的代码在

之下
import UIKit
import AVFoundation
import Firebase


class ScanController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

var captureSession: AVCaptureSession?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var qrCodeFrameView: UIView?


let itemDB = FIRDatabase.database().reference().child("Items")

let supportedCodeTypes = [AVMetadataObjectTypeUPCECode,
                          AVMetadataObjectTypeCode39Code,
                          AVMetadataObjectTypeCode39Mod43Code,
                          AVMetadataObjectTypeCode93Code,
                          AVMetadataObjectTypeCode128Code,
                          AVMetadataObjectTypeEAN8Code,
                          AVMetadataObjectTypeEAN13Code,
                          AVMetadataObjectTypeAztecCode,
                          AVMetadataObjectTypePDF417Code,
                          AVMetadataObjectTypeQRCode]
let messageLabel: UILabel = {
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
    // label.center = CGPoint(x: 160, y: 285)
    label.center = CGPoint(x: 160, y: 285)
    label.textAlignment = .center
    return label
}()
let productDescriptionTextField: UITextField = {
    let tf = UITextField()
    tf.placeholder = "Product Description"
    tf.translatesAutoresizingMaskIntoConstraints = false
    return tf
}()
let descriptionSeparatorView: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor(r: 220, g: 220, b: 220)
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()
let priceTextField: UITextField = {
    let tf = UITextField()
    tf.placeholder = "Price"
    tf.translatesAutoresizingMaskIntoConstraints = false
    return tf
}()
let priceSeparatorView: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor(r: 220, g: 220, b: 220)
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()
let productLocationTextField: UITextField = {
    let tf = UITextField()
    tf.placeholder = "Product Location"
    tf.translatesAutoresizingMaskIntoConstraints = false
    return tf
}()
let productImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.image = UIImage(named: "XXXXXXX")
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.contentMode = .scaleAspectFill
    return imageView
}()
let exitScanButton: UIButton = {
    let button = UIButton(type: .system)
    button.backgroundColor = UIColor(r: 80, g: 101, b: 161)
    button.setTitle("Exit", for: .normal)
    button.setTitleColor(UIColor.white, for: .normal)
    button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.addTarget( nil, action: #selector(exitScan), for:.touchUpInside)
    return button
}()
let newProductEntry: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor.white
    view.translatesAutoresizingMaskIntoConstraints = false
    view.layer.cornerRadius = 5
    view.layer.masksToBounds = true
    return view
}()
let productSummary: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor.white
    view.translatesAutoresizingMaskIntoConstraints = false
    view.layer.cornerRadius = 5
    view.layer.masksToBounds = true
    return view
}()
let productDescriptionLabel: UILabel = {
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
    // label.center = CGPoint(x: 160, y: 285)
    label.center = CGPoint(x: 160, y: 285)
    label.textAlignment = .center
    return label
}()
let storeNameLabel: UILabel = {
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
    // label.center = CGPoint(x: 160, y: 285)
    label.center = CGPoint(x: 160, y: 285)
    label.textAlignment = .center
    return label
}()
let verifyProductInfoButton: UIButton = {
    let button = UIButton(type: .system)
    button.backgroundColor = UIColor(r: 80, g: 101, b: 161)
    button.setTitle("Checked", for: .normal)
    button.setTitleColor(UIColor.white, for: .normal)
    button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
    button.translatesAutoresizingMaskIntoConstraints = false

    button.addTarget( nil, action: #selector(verifyNewProduct), for:.touchUpInside)
    return button
}()
let updateProductInfoButton: UIButton = {
    let button = UIButton(type: .system)
    button.backgroundColor = UIColor(r: 80, g: 101, b: 161)
    button.setTitle("Update", for: .normal)
    button.setTitleColor(UIColor.white, for: .normal)
    button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
    button.translatesAutoresizingMaskIntoConstraints = false

    button.addTarget( nil, action: #selector(updateProductInfo), for:.touchUpInside)
    return button
}()

let enterNewProductButton: UIButton = {
    let button = UIButton(type: .system)
    button.backgroundColor = UIColor(r: 80, g: 101, b: 161)
    button.setTitle("Enter", for: .normal)
    button.setTitleColor(UIColor.white, for: .normal)
    button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
    button.translatesAutoresizingMaskIntoConstraints = false

    button.addTarget( nil, action: #selector(enterNewProduct), for:.touchUpInside)
    return button
}()
func updateProductInfo() {
    guard let price = priceTextField.text,
        let location = productLocationTextField.text
        else{
            print("Please update price and product location")
            return
    }

}
func verifyNewProduct() {
    // need to add a counter that counts how many people verified product information
    self.dismiss(animated: true, completion: nil)
}

func enterNewProduct() {
    let itemID = metadataObj.stringValue
    guard let Description = productDescriptionTextField.text,
        let price = priceTextField.text,
        let location = productLocationTextField.text
        else{
            print("Fill basic product information")
            return
    }

    let ref = FIRDatabase.database().reference(fromURL: "")
    // creating an  item child node
    let values = ["Item Description": Description, "Image": price, "Location": location, "Price": price ]

    let items = ref.child("Items").child(itemID!)
    items.updateChildValues(values, withCompletionBlock: { (err, ref) in
        if err != nil {
            print(err)
            return
        }
    })
     self.dismiss(animated: true, completion: nil)

}
func exitScan() {
    //Go back to ViewController
    self.dismiss(animated: true, completion: nil)

}
func setupUpdateProductInfo() {
    productSummary.addSubview(productDescriptionLabel)
    productSummary.addSubview(storeNameLabel)
    productSummary.addSubview(priceTextField)
    productSummary.addSubview(productLocationTextField)
    productSummary.addSubview(verifyProductInfoButton)
    productSummary.addSubview(updateProductInfoButton)
    productSummary.addSubview(productImageView)

    // need x, y, width, height constraints for product image
    productImageView.leftAnchor.constraint(equalTo: productSummary.leftAnchor, constant: 12).isActive = true
    productImageView.topAnchor.constraint(equalTo: productSummary.topAnchor).isActive = true
    productImageView.widthAnchor.constraint(equalTo: productSummary.widthAnchor, constant: 100).isActive = true
    productImageView.heightAnchor.constraint(equalToConstant: 100).isActive = true

    // need x, y, width, height constraints for store logo
    storeNameLabel.leftAnchor.constraint(equalTo: productDescriptionLabel.leftAnchor, constant: 12).isActive = true
    storeNameLabel.topAnchor.constraint(equalTo: productSummary.topAnchor).isActive = true
    storeNameLabel.widthAnchor.constraint(equalTo: productSummary.widthAnchor).isActive = true

    // need x, y, width, height constraints for description label
    productDescriptionLabel.leftAnchor.constraint(equalTo: productImageView.leftAnchor, constant: 12).isActive = true
    productDescriptionLabel.topAnchor.constraint(equalTo: productSummary.topAnchor).isActive = true
    productDescriptionLabel.widthAnchor.constraint(equalTo: productSummary.widthAnchor).isActive = true
    productDescriptionLabel.rightAnchor.constraint(equalTo: storeNameLabel.leftAnchor,constant: 12).isActive = true

    // need x, y, width, height constraints for price textfield
    priceTextField.leftAnchor.constraint(equalTo: productImageView.rightAnchor, constant: 12).isActive = true
    priceTextField.topAnchor.constraint(equalTo: productDescriptionLabel.bottomAnchor).isActive = true
    priceTextField.widthAnchor.constraint(equalToConstant: 50).isActive = true

    // need x, y, width, height constraints for location textfield 
    productLocationTextField.leftAnchor.constraint(equalTo: priceTextField.rightAnchor, constant: 12).isActive = true
    productLocationTextField.topAnchor.constraint(equalTo: productDescriptionLabel.bottomAnchor).isActive = true
    productLocationTextField.widthAnchor.constraint(equalToConstant: 50).isActive = true

}
func setupNewProductEntry() {
    newProductEntry.addSubview(productImageView)
    newProductEntry.addSubview(productLocationTextField)
    newProductEntry.addSubview(productDescriptionTextField)
    newProductEntry.addSubview(priceTextField)
    newProductEntry.addSubview(enterNewProductButton)
    newProductEntry.addSubview(descriptionSeparatorView)
    newProductEntry.addSubview(priceSeparatorView)

    // need x, y, width, height constraints
    newProductEntry.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    newProductEntry.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
    newProductEntry.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true
    newProductEntry.heightAnchor.constraint(equalToConstant: 150).isActive = true

    // need x, y, width, height constraints for name productDescriptionTextField
    productDescriptionTextField.leftAnchor.constraint(equalTo: newProductEntry.leftAnchor, constant: 12).isActive = true
    productDescriptionTextField.topAnchor.constraint(equalTo: newProductEntry.topAnchor).isActive = true
    productDescriptionTextField.widthAnchor.constraint(equalTo: newProductEntry.widthAnchor).isActive = true

    // need x, y, width, height constraints for description separator line
    descriptionSeparatorView.leftAnchor.constraint(equalTo: newProductEntry.leftAnchor).isActive = true
    descriptionSeparatorView.topAnchor.constraint(equalTo: productDescriptionTextField.bottomAnchor).isActive = true
    descriptionSeparatorView.widthAnchor.constraint(equalTo: newProductEntry.widthAnchor).isActive = true
    descriptionSeparatorView.heightAnchor.constraint(equalToConstant: 1).isActive = true

    // need x, y, width, height constraints for name pricetextfield
    priceTextField.leftAnchor.constraint(equalTo: newProductEntry.leftAnchor, constant: 12).isActive = true
    priceTextField.topAnchor.constraint(equalTo: productDescriptionTextField.bottomAnchor).isActive = true
    priceTextField.widthAnchor.constraint(equalTo: newProductEntry.widthAnchor).isActive = true

    // need x, y, width, height constraints for price separator line
    priceSeparatorView.leftAnchor.constraint(equalTo: newProductEntry.leftAnchor).isActive = true
    priceSeparatorView.topAnchor.constraint(equalTo: priceTextField.bottomAnchor).isActive = true
    priceSeparatorView.widthAnchor.constraint(equalTo: newProductEntry.widthAnchor).isActive = true
    priceSeparatorView.heightAnchor.constraint(equalToConstant: 1).isActive = true

    // need x, y, width, height constraints for name LocationTextField
    productLocationTextField.leftAnchor.constraint(equalTo: newProductEntry.leftAnchor, constant: 12).isActive = true
    productLocationTextField.topAnchor.constraint(equalTo: priceTextField.bottomAnchor).isActive = true
    productLocationTextField.widthAnchor.constraint(equalTo: newProductEntry.widthAnchor).isActive = true
}

func setupenterNewProductButton(){
    // need x, y, width, height constraints
    enterNewProductButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    enterNewProductButton.topAnchor.constraint(equalTo: newProductEntry.bottomAnchor, constant: 12).isActive = true
    enterNewProductButton.widthAnchor.constraint(equalTo: newProductEntry.widthAnchor).isActive = true
    enterNewProductButton.heightAnchor.constraint(equalToConstant: (50)).isActive = true
}
func setupupdateProductInfoButton(){
// need x, y, width, height constraints
    updateProductInfoButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    updateProductInfoButton.topAnchor.constraint(equalTo: productSummary.bottomAnchor, constant: 12).isActive = true
    updateProductInfoButton.widthAnchor.constraint(equalTo: productSummary.widthAnchor).isActive = true
    updateProductInfoButton.heightAnchor.constraint(equalToConstant: (50)).isActive = true
}
func setupverifyProductInfoButton(){
    // need x, y, width, height constraints
    verifyProductInfoButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    verifyProductInfoButton.topAnchor.constraint(equalTo: productSummary.bottomAnchor, constant: 12).isActive = true
    verifyProductInfoButton.widthAnchor.constraint(equalTo: productSummary.widthAnchor).isActive = true
    verifyProductInfoButton.heightAnchor.constraint(equalToConstant: (50)).isActive = true
    verifyProductInfoButton.leftAnchor.constraint(equalTo: enterNewProductButton.rightAnchor).isActive = true
}

override func viewDidLoad() {
    super.viewDidLoad()

    //Get an instance of the AVCaptureDevice class  a device object and provide the video as the media type parameter
    let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

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

        // Initialize the captureSession object.
         captureSession = AVCaptureSession()

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

        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 = supportedCodeTypes
        // Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
        videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
        videoPreviewLayer?.frame = view.layer.bounds
        view.layer.addSublayer(videoPreviewLayer!)

        // Start video capture.
        captureSession?.startRunning()

        // Add the message label
        self.view.addSubview(messageLabel)
        self.view.addSubview(exitScanButton)


        setupexitScanButton()

        //initialize QR Code Frame to highlight the QR Code
        qrCodeFrameView = UIView()

        if let qrCodeFrameView = qrCodeFrameView {
            qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
            qrCodeFrameView.layer.borderWidth = 2
            view.addSubview(qrCodeFrameView)
        }
    } catch {

        // If any error occurs, simply print it out and don't continue any more.
        print(error)
        return
    }
}

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

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {

    // Check if the metadataObjects array is not nil and it contains at least one object.
    if metadataObjects == nil || metadataObjects.count == 0 {
        qrCodeFrameView?.frame = CGRect.zero
        messageLabel.text = "No QR/barcode is detected"
        return
    }
    //Get metadata object
    let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
    let itemID = metadataObj.stringValue




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

        if metadataObj.stringValue != nil {
            messageLabel.text = metadataObj.stringValue

            //Searches firebase for existing barcode 
            let itemToSearchFor = metadataObj.stringValue


             FIRDatabase.database().reference().child("Items").child(itemToSearchFor!).observeSingleEvent(of: .value, with:{(snap) in

                print(snap)

             }) } else {

                setupNewProductEntry()

            }
    }


        }






func setupexitScanButton() {
    // need x, y, width, height constraints
    exitScanButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    exitScanButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 12).isActive = true
    exitScanButton.widthAnchor.constraint(equalToConstant: 60).isActive = true
    exitScanButton.heightAnchor.constraint(equalToConstant: (50)).isActive = true

}
}

我的错误目前位于let itemID = metadataObj.stringValue

1 个答案:

答案 0 :(得分:0)

在qrcodeframeview的顶部定义它,使其在您的班级中“全局”