2016-11-14 13 views
0

私はバーコードスキャナを構築しています。操作は簡単です バーコードをスキャンすると バーコードが私のfirebaseデータベースにある場合はfunc updateProductInfo()バーコードがfirebaseデータベースにない場合はfunc enterNewProduct()を実行します。 今私が抱えている問題の1つは、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にあります。

+0

あなたのクラスで、それは「グローバル」にするためにqrcodeframeview下のトップでそれを定義します。どちらがエラーを出すのですか?それらのすべて? – Honey

+0

私のエラーは現在funcであるenterNewProduct()let itemID = metadataObj.stringValue。 –

答えて

0

あなたは `聞かせITEMID = metadataObj.stringValue`の複数行を持って

+0

はい私が知っている、私の問題は実際に定義する方法です –

+0

他の変数と同じように一番上に定義し、それを使ったときに再割り当てすることができます。 –

+0

時間のおかげでパトリック。私はそれを把握します。 –

関連する問題