2016-11-16 4 views
1

すべての機能でグローバルにアクセスできるように、バーコードスキャンをどのように定義できますか?つまり、どのようにして "metadataObj"をグローバルに定義できますか?未解決の識別子「itemID」

class ScanController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 

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

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() 

    //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 
} 
} 

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 

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 
     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 
      } }) 
     FIRDatabase.database().reference().child("Items").child(itemToSearchFor!).observeSingleEvent(of: .value, with:{(snap) in 

       print(snap) 

        }) 

      self.setupNewProductEntry() 
      self.setupenterNewProductButton() 
} 

      } 

別の機能でItemIDを使用しようとしたときに1つのエラーが発生しました。これは、グローバルに定義されていないためです.func captureOutput内でのみ定義されています。私がバーコードスキャナーから得たバーコード文字列の値をグローバルに定義する方法に関するアイデアはありますか?

答えて

0

(コメントがどこにあるか)

0

がそれにアクセスできるように、ここでそれを宣言するあなたのクラスのスコープを超えて移動することができますので、それはすべてあなたのモジュールを介してグローバルと見えるようになります。それはもう、クラスのメンバーではないよう

class ScanController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 

var captureSession: AVCaptureSession? 
var videoPreviewLayer: AVCaptureVideoPreviewLayer? 
var qrCodeFrameView: UIView? 
//DECLARE itemID here 
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) 
+0

ありがとうアレック、私はそれを定義する必要があることを知っています。私の問題は本当にコーディングです。私は多くの方法を試みました。 let itemID = AVCaptureMetadataOutput.stringと他の多くの方法で定義しようとする必要がありましたが、動作しませんでした。 @vlad – Ola

0

だけで、(クラス宣言の外に、私は意味、インポートセクションの後に、ファイルの先頭を)グローバルスコープ内のクラスの外に「metadataObjを」置きます(そしてあなたの選択した値で初期化します)。それをフレームワークで宣言してアプリで使用する場合は、publicアクセス修飾子を追加するか、アクセスできません。 クラスのスコープに配置したいがコード内のどこからでもアクセスできるようにするには、静的修飾子(またはフレームワークで宣言する場合はスタティックパブリック)を追加します。 staticを使用すると、クラスの特定のインスタンス(クラスのすべてのインスタンスで共有されているmetadataObjの1つのみのインスタンス)に関係なく、変数の1つのインスタンスが作成されます。異なるスレッドからmetadataObjにアクセスする場合は注意してください...非常に厄介な不具合に直面する可能性があり、修正が難しいです。後者の場合、スレッドの同期を考慮してください(対処するのは簡単なテーマではありません)...あなたが何をする必要があるかについての非常に明確な考え方がない場合、私はそれを抑止します。代わりに、クラスのスコープ内でのみ必要な場合(つまり、すべてのメンバ関数によって使用されることを意味します)、アレックがあなたに言った場所に配置します。

関連する問題