代碼: 選擇全部
import UIKit
import AVFoundation
class BarcodeController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
let session : AVCaptureSession = AVCaptureSession()
var previewLayer : AVCaptureVideoPreviewLayer!
var highlightView : UIView = UIView()
@IBOutlet weak var flashButton: UIBarButtonItem!
func CheckCamera() {
let authStatus = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)
switch authStatus {
case AVAuthorizationStatus.Authorized: AllowScanning() // Do you stuffer here i.e. allowScanning()
case AVAuthorizationStatus.Denied: alertToEncourageCameraAccessInitially()
case AVAuthorizationStatus.NotDetermined: alertPromptToAllowCameraAccessViaSetting()
default: alertToEncourageCameraAccessInitially()
}
}
func alertToEncourageCameraAccessInitially() {
let alert = UIAlertController(title: "IMPORTANT", message: "Please allow camera access for Scanning", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: nil))
alert.addAction(UIAlertAction(title: "Allow Camera", style: .Cancel, handler: { (alert) -> Void in
UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
}))
presentViewController(alert, animated: true, completion: nil)
}
func alertPromptToAllowCameraAccessViaSetting() {
let alert = UIAlertController(title: "IMPORTANT", message: "Please allow camera access for Scanning", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Dismiss", style: .Cancel) { alert in
if AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo).count > 0 {
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo) { granted in
dispatch_async(dispatch_get_main_queue()) {
self.CheckCamera() } }
}
})
presentViewController(alert, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
self.ShowFlash()
self.CheckCamera()
if(AVCaptureDevice.devices().count == 0)
{
print("No AV capture device found.")
return
}
}
func AllowScanning()
{
// Allow the view to resize freely
self.highlightView.autoresizingMask = [.FlexibleTopMargin, .FlexibleBottomMargin, .FlexibleLeftMargin, .FlexibleRightMargin]
// Select the color you want for the completed scan reticle
self.highlightView.layer.borderColor = UIColor.greenColor().CGColor
self.highlightView.layer.borderWidth = 3
// Add it to our controller's view as a subview.
self.view.addSubview(self.highlightView)
// For the sake of discussion this is the camera
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
// Create a nilable NSError to hand off to the next method.
// Make sure to use the "var" keyword and not "let"
let error : NSError? = nil
do {
let input : AVCaptureDeviceInput? = try AVCaptureDeviceInput(device: device) as AVCaptureDeviceInput
// If our input is not nil then add it to the session, otherwise we're kind of done!
if input != nil {
session.addInput(input)
}
else {
// This is fine for a demo, do something real with this in your app. :)
print(error)
}
let output = AVCaptureMetadataOutput()
output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
session.addOutput(output)
output.metadataObjectTypes = output.availableMetadataObjectTypes
}
catch
{
print(error)
}
previewLayer = AVCaptureVideoPreviewLayer(session: session) as AVCaptureVideoPreviewLayer
previewLayer.frame = self.view.bounds
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
self.view.layer.addSublayer(previewLayer)
// Start the scanner. You'll have to end it yourself later.
session.startRunning()
}
// This is called when we find a known barcode type with the camera.
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
var highlightViewRect = CGRectZero
var barCodeObject : AVMetadataObject!
var detectionString : String!
let barCodeTypes = [AVMetadataObjectTypeUPCECode,
AVMetadataObjectTypeCode39Code,
AVMetadataObjectTypeCode39Mod43Code,
AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeCode93Code,
AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypePDF417Code,
AVMetadataObjectTypeQRCode,
AVMetadataObjectTypeAztecCode
]
// The scanner is capable of capturing multiple 2-dimensional barcodes in one scan.
for metadata in metadataObjects {
for barcodeType in barCodeTypes {
if metadata.type == barcodeType {
barCodeObject = self.previewLayer.transformedMetadataObjectForMetadataObject(metadata as! AVMetadataMachineReadableCodeObject)
highlightViewRect = barCodeObject.bounds
detectionString = (metadata as! AVMetadataMachineReadableCodeObject).stringValue
self.session.stopRunning()
break
}
}
}
self.navigationItem.title = detectionString
print(detectionString)
self.highlightView.frame = highlightViewRect
self.view.bringSubviewToFront(self.highlightView)
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
session.startRunning()
}
override func viewDidLayoutSubviews() {
if(AVCaptureDevice.devices().count > 0)
{
if let previewLayer = self.previewLayer {
previewLayer.frame = self.view.bounds
if (previewLayer.connection.supportsVideoOrientation) {
previewLayer.connection.videoOrientation = interfaceOrientationToVideoOrientation(UIApplication.sharedApplication().statusBarOrientation)
}
}
}
}
func interfaceOrientationToVideoOrientation(orientation : UIInterfaceOrientation) -> AVCaptureVideoOrientation {
switch (orientation) {
case UIInterfaceOrientation.Portrait:
return AVCaptureVideoOrientation.Portrait;
case UIInterfaceOrientation.PortraitUpsideDown:
return AVCaptureVideoOrientation.PortraitUpsideDown;
case UIInterfaceOrientation.LandscapeLeft:
return AVCaptureVideoOrientation.LandscapeLeft;
case UIInterfaceOrientation.LandscapeRight:
return AVCaptureVideoOrientation.LandscapeRight;
default:
print("Warning - Didn't recognise interface orientation")
return AVCaptureVideoOrientation.Portrait;
}
}
func ShowFlash()
{
flashButton.image = UIImage(named: "flash-off")
flashButton.enabled = false
if(AVCaptureDevice.devices().count > 0)
{
let flashDevice: AVCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
if(flashDevice.hasTorch && flashDevice.hasFlash)
{
flashButton.enabled = true
flashButton.image = UIImage(named: "flash")
}
}
}
@IBAction func toggleFlash(sender: UIBarButtonItem)
{
let flashDevice: AVCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
if(flashDevice.hasTorch && flashDevice.hasFlash)
{
do {
try flashDevice.lockForConfiguration()
if (flashDevice.torchMode == AVCaptureTorchMode.On) {
flashDevice.torchMode = AVCaptureTorchMode.Off
} else {
try flashDevice.setTorchModeOnWithLevel(1.0)
}
flashDevice.unlockForConfiguration()
} catch {
print(error)
}
}
}
}