swift4 qr reader working but no result - swift

swift4 qr-code reader and suppose to popup an alert, but it didn't show the popup alert.
The session start running properly, but the func captureOutput() seems not trigger when qr-code scanned.
my code:
import UIKit
import AVFoundation
class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
#IBOutlet weak var square: UIImageView!
//Creating session
var video = AVCaptureVideoPreviewLayer()
override func viewDidLoad() {
super.viewDidLoad()
//Creating session
let session = AVCaptureSession()
//Define capture devcie
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
do
{let input = try AVCaptureDeviceInput(device: captureDevice!)
session.addInput(input)}
catch
{ print ("ERROR")}
let output = AVCaptureMetadataOutput()
session.addOutput(output)
output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
output.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
video = AVCaptureVideoPreviewLayer(session: session)
video.frame = view.layer.bounds
view.layer.addSublayer(video)
self.view.bringSubview(toFront: square)
session.startRunning()
}
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
if metadataObjects != nil && metadataObjects.count != 0
{
if let object = metadataObjects[0] as? AVMetadataMachineReadableCodeObject
{
if object.type == AVMetadataObject.ObjectType.qr
{
let alert = UIAlertController(title: "QR Code", message: object.stringValue, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Retake", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "Copy", style: .default, handler: { (nil) in
UIPasteboard.general.string = object.stringValue
}))
present(alert, animated: true, completion: nil)
}
}
}
}
}

Your scanning code check will be in the following delegate:
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)
Your code will be like this:
import UIKit
import AVFoundation
class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
#IBOutlet weak var square: UIImageView!
//Creating session
var video = AVCaptureVideoPreviewLayer()
override func viewDidLoad() {
super.viewDidLoad()
//Creating session
let session = AVCaptureSession()
//Define capture devcie
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
do
{let input = try AVCaptureDeviceInput(device: captureDevice!)
session.addInput(input)}
catch
{ print ("ERROR")}
let output = AVCaptureMetadataOutput()
session.addOutput(output)
output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
output.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
video = AVCaptureVideoPreviewLayer(session: session)
video.frame = view.layer.bounds
view.layer.addSublayer(video)
self.view.bringSubview(toFront: square)
session.startRunning()
}
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if metadataObjects != nil && metadataObjects.count != 0
{
if let object = metadataObjects[0] as? AVMetadataMachineReadableCodeObject
{
if object.type == AVMetadataObject.ObjectType.qr
{
let alert = UIAlertController(title: "QR Code", message: object.stringValue, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Retake", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "Copy", style: .default, handler: { (nil) in
UIPasteboard.general.string = object.stringValue
}))
present(alert, animated: true, completion: nil)
}
}
}
}
}

Related

I want to add an ean 13 barcode scanner to my application but it wont work on swift playgrounds for Ipad

I am trying to add an scanner to my application but everytime when I run the application it sais that there is a problem in my code and that I have to try again
The code what I have is from https://www.hackingwithswift.com/example-code/media/how-to-scan-a-barcode, I tried to paste it on to an blank document and a Xcode-playground document but both of them didn’t work.
Import AVFoundation
import UIKit
class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black
captureSession = AVCaptureSession()
guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return }
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: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [.ean8, .ean13, .pdf417]
} else {
failed()
return
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = .resizeAspectFill
view.layer.addSublayer(previewLayer)
captureSession.startRunning()
}
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))
present(ac, animated: true)
captureSession = nil
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if (captureSession?.isRunning == false) {
captureSession.startRunning()
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if (captureSession?.isRunning == true) {
captureSession.stopRunning()
}
}
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
captureSession.stopRunning()
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
guard let stringValue = readableObject.stringValue else { return }
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue)
}
dismiss(animated: true)
}
func found(code: String) {
print(code)
}
override var prefersStatusBarHidden: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
}

How to show scanned QRCode user profile in my app in swift

First time i am working with QRCode
in our app i need to show the scanned user profile in my app when i scan that user QRCode in my app.. how to show scanned user profile in my app
i have written code for scan the user QRCode.. if i scan correct QRCode then here how to show that person profile in my app
code for scan the qrcode scanner:
import UIKit
import AVFoundation
class QRCodeViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var video = AVCaptureVideoPreviewLayer()
let session = AVCaptureSession()
#IBOutlet weak var qrCode: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
guard let captureDevice = AVCaptureDevice.default(for: AVMediaType.video) else { return }
do{
let input = try AVCaptureDeviceInput(device: captureDevice)
session.addInput(input)
}catch{print("error")}
let output = AVCaptureMetadataOutput()
session.addOutput(output)
output.setMetadataObjectsDelegate(self, queue:DispatchQueue.main)
output.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
video = AVCaptureVideoPreviewLayer(session: session)
video.frame = view.layer.bounds
view.layer.addSublayer(video)
self.view.bringSubviewToFront(qrCode)
session.startRunning()
}
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if metadataObjects != nil && metadataObjects.count != 0{
if let object = metadataObjects[0] as? AVMetadataMachineReadableCodeObject{
if object.type == AVMetadataObject.ObjectType.qr{
let alert = UIAlertController(title: "QR Code", message: object.stringValue, preferredStyle: .alert)
alert.addAction(UIAlertAction(title:"Retake", style: .default, handler: nil))
alert.addAction(UIAlertAction(title:"Confirm", style: .default, handler: { (nil) in
// self.scannedCode = object.stringValue!
self.session.stopRunning() }))
present(alert, animated: true, completion: nil)
}
}
}
}
}
by using above code if i scan correct QRCode of user, then how to show that person profile in my screen.. please suggest me..

Unsupported type found - use -availableMetadataObjectTypes' issue

I am trying to create QR Reader. However, when I open the window with scanner, it crashes with error "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVCaptureMetadataOutput setMetadataObjectTypes:] Unsupported type found - use -availableMetadataObjectTypes'"
This is my code:
import UIKit
import AVFoundation
import Alamofire
import SwiftyJSON
class CameraTwoViewController: UIViewController,
AVCaptureMetadataOutputObjectsDelegate {
#IBOutlet weak var square: UIImageView!
var video = AVCaptureVideoPreviewLayer()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Creating session
let session = AVCaptureSession()
//Define capture devcie
let captureDevice = AVCaptureDevice.default(for: .video)
do
{
let input = try AVCaptureDeviceInput(device: captureDevice!)
}
catch
{
print ("ERROR")
}
let output = AVCaptureMetadataOutput()
session.addOutput(output)
output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
output.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
//output.metadataObjectTypes = [AVMetadataObject.availableMetadataObjectTypes.qr]
video = AVCaptureVideoPreviewLayer(session: session)
video.frame = view.layer.bounds
view.layer.addSublayer(video)
self.view.bringSubview(toFront: square)
session.startRunning()
}
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if metadataObjects != nil && metadataObjects.count != 0 {
if let object = metadataObjects[0] as? AVMetadataMachineReadableCodeObject {
if object.type == AVMetadataObject.ObjectType.qr {
let alert = UIAlertController(title: "Your code is:", message: object.stringValue, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Retake", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "Copy", style: .default, handler: { (nil) in
UIPasteboard.general.string = object.stringValue
}))
present(alert, animated: true, completion: nil)
}
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Thank you in advance!
Try to add input to the session before you add output. Something like that:
func configureScanner() {
guard let captureDevice = AVCaptureDevice.default(for: .video) else {
return
}
var input: AVCaptureDeviceInput?
do {
input = try AVCaptureDeviceInput(device: captureDevice)
} catch let error {
print(error.localizedDescription)
}
guard let indeedInput = input else {
return
}
captureSession = AVCaptureSession()
captureSession!.addInput(indeedInput)
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession!.addOutput(captureMetadataOutput)
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
captureMetadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
...
}

Opening an URL scanned from a QR code in SFSafariViewController

I'm trying to make my app open the scanned url from qr codes. I made a qr code scanner but it only copies the value of the scanned qr code to the pasteboard. I'm trying to make it open it in a SFSafariViewController.
instead of "Copy" option, I want to make it "Open" and actually open the scanned url.
Here's my code
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
if metadataObjects != nil && metadataObjects.count != 0
{
if let object = metadataObjects[0] as? AVMetadataMachineReadableCodeObject
{
if object.type == AVMetadataObjectTypeQRCode
{
let alert = UIAlertController(title: "QR Code", message: object.stringValue, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Retake", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "Copy", style: .default, handler: { (nil) in
UIPasteboard.general.string = object.stringValue
}))
present(alert, animated: true, completion: nil)
}
}
}
}
Using safariviewController is pretty straightforward
First you have to import safariservices and then present the safaricontroller with a url
The basic codes to this are
import SafariServices
func loadSafari(url : String){
guard let url = URL(string: url) else { return }
let safariController = SFSafariViewController(url: url)
present(safariController, animated: true, completion: nil)
}
place this code in your class and call the function inside your capture output
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
if metadataObjects != nil && metadataObjects.count != 0
{
if let object = metadataObjects[0] as? AVMetadataMachineReadableCodeObject
{
if object.type == AVMetadataObjectTypeQRCode
{
UIPasteboard.general.string = object.stringValue
loadSafari(url: object.stringValue)
}))
present(alert, animated: true, completion: nil)
}
}
}
}
clicking on the done will dismiss the safariController and have the user navigate back to the previous viewcontroller.
I hope this helps. Let me know how it goes.
Your code shows no sign of attempting to use the SFSafariViewController. Have you tried something like the below?
import SafariServices
if let url = URL(string: object.stringValue) {
let browser = SFSafariViewController(url: url)
}
This won't make it magically appear, there will still be some work you need to do yourself to present it to the user such as:
presentViewController(browser, animated: true, completion: nil)

Improve reading QR and PDF417 code with AVFoundation swift

I'm trying to read PDF-417 and QR code and my code works but when there is less light or blurred image does not work. So I am looking for information about how may improve reading code.
I tried changing the settings on the camera: AVCaptureSession Increased the resolution settings and the AVCaptureDevice Increased videoZoomFactor but apparently I'm not doing it correctly.
I hope you can help me.
import UIKit
import AVFoundation
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
let session : AVCaptureSession = AVCaptureSession()
var previewLayer : AVCaptureVideoPreviewLayer!
var highlightView : UIView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
/
self.highlightView.autoresizingMask = UIViewAutoresizing.FlexibleTopMargin |
UIViewAutoresizing.FlexibleBottomMargin |
UIViewAutoresizing.FlexibleLeftMargin |
UIViewAutoresizing.FlexibleRightMargin
/
self.highlightView.layer.borderColor = UIColor.greenColor().CGColor
self.highlightView.layer.borderWidth = 3
/
self.view.addSubview(self.highlightView)
/
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
/
/
var error : NSError? = nil
let input : AVCaptureDeviceInput? = AVCaptureDeviceInput.deviceInputWithDevice(device, error: &error) as? AVCaptureDeviceInput
/
if input != nil {
session.addInput(input)
}
else {
/
println(error)
}
let output = AVCaptureMetadataOutput()
output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
session.addOutput(output)
output.metadataObjectTypes = output.availableMetadataObjectTypes
previewLayer = AVCaptureVideoPreviewLayer.layerWithSession(session) as! AVCaptureVideoPreviewLayer
previewLayer.frame = self.view.bounds
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
self.view.layer.addSublayer(previewLayer)
/
session.startRunning()
}
/
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
var highlightViewRect = CGRectZero
var barCodeObject : AVMetadataMachineReadableCodeObject!
var detectionString : String!
let barCodeTypes = [
AVMetadataObjectTypePDF417Code,
AVMetadataObjectTypeQRCode
]
/
for metadata in metadataObjects {
for barcodeType in barCodeTypes {
if metadata.type == barcodeType
{
barCodeObject = self.previewLayer.transformedMetadataObjectForMetadataObject(metadata as! AVMetadataMachineReadableCodeObject) as! AVMetadataMachineReadableCodeObject
highlightViewRect = barCodeObject.bounds
detectionString = (metadata as! AVMetadataMachineReadableCodeObject).stringValue
self.session.stopRunning()
self.alert(detectionString)
break
}
}
}
println(detectionString)
self.highlightView.frame = highlightViewRect
self.view.bringSubviewToFront(self.highlightView)
}
func alert(Code: String)
{
let actionSheet:UIAlertController = UIAlertController(title: "Barcode", message: "\(Code)", preferredStyle: UIAlertControllerStyle.Alert)
let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler:
{
(alertAction:UIAlertAction!) in
self.session.startRunning()
})
actionSheet.addAction(firstAlertAction)
self.presentViewController(actionSheet, animated: true, completion: nil)
}
}
I struggled with unconsistent reading of qr-codes, what worked for me was to get the qr-code as proportional as possible. (If reading from another iphone/ipad screen) If that doesnt help you, the http://www.appcoda.com/qr-code-reader-swift/ <-- helped me out
cheers