Skip to content

Instantly share code, notes, and snippets.

@willianpinho
Last active March 16, 2018 17:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save willianpinho/9c3d503ea0d1e0d215bf5bdfb9b3235b to your computer and use it in GitHub Desktop.
Save willianpinho/9c3d503ea0d1e0d215bf5bdfb9b3235b to your computer and use it in GitHub Desktop.
Gist for DevGrid
//
// ViewController.swift
// QR-Gist
//
// Created by Willian Pinho on 16/03/18.
// Copyright © 2018 Willian Pinho. All rights reserved.
//
import UIKit
class MainViewController: UIViewController {
@IBOutlet weak var qrImageView: UIImageView!
@IBOutlet weak var scanGistButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
definesPresentationContext = true
self.customLayout()
}
override func viewWillAppear(_ animated: Bool) {
self.navigationController?.isNavigationBarHidden = true
}
func customLayout() {
addGestureImage(image: qrImageView, selector: #selector(openLink))
scanGistButton.addTarget(self, action: #selector(goToScan), for: UIControlEvents.touchUpInside)
}
func addGestureImage(image: UIImageView, selector: Selector) {
let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: selector)
image.isUserInteractionEnabled = true
image.addGestureRecognizer(longPressGestureRecognizer)
}
@objc func openLink() {
let actionSheet = UIAlertController(title: "I'm also very curious ", message: nil, preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Open My LinkedIn Profile", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
guard let url = URL(string: "linkedin://profile/willianpinho") else {
return print("Can't Open Link ")
}
self.openUrl(url: url)
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(actionSheet, animated: true, completion: nil)
}
func openUrlWithSafari() {
guard let url = URL(string: "https://www.linkedin.com/in/willianpinho/") else {
return print("Erro ao abrir link")
}
self.openUrl(url: url)
}
func openUrl(url:URL) {
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: { (success) in
if !success {
self.openUrlWithSafari()
}
})
} else {
UIApplication.shared.open(url, options: [:], completionHandler: { (success) in
if !success {
self.openUrlWithSafari()
}
})
}
}
@objc func goToScan() {
self.openViewControllerWithIdentifier(storyBoard: "Main", identifier: "ScanViewController")
}
}
//
// ScanViewController.swift
// QR-Gist
//
// Created by Willian Pinho on 16/03/18.
// Copyright © 2018 Willian Pinho. All rights reserved.
//
import UIKit
import AVFoundation
class ScanViewController: UIViewController {
@IBOutlet weak var bottomLabel: UILabel!
var captureSession = AVCaptureSession()
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var qrCodeFrameView: UIView?
private let supportedCodeTypes = [AVMetadataObject.ObjectType.qr]
override func viewDidLoad() {
super.viewDidLoad()
self.customLayout()
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera], mediaType: AVMediaType.video, position: .back)
guard let captureDevice = deviceDiscoverySession.devices.first else {
print("Failed to get the camera device")
return
}
do {
// Get an instance of the AVCaptureDeviceInput class using the previous device object.
let input = try AVCaptureDeviceInput(device: captureDevice)
// Set the input device on the capture session.
captureSession.addInput(input)
// Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
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
// captureMetadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
} catch {
// If any error occurs, simply print it out and don't continue any more.
print(error)
return
}
// Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
videoPreviewLayer?.frame = view.layer.bounds
view.layer.addSublayer(videoPreviewLayer!)
// Start video capture.
captureSession.startRunning()
view.bringSubview(toFront: bottomLabel)
// 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)
view.bringSubview(toFront: qrCodeFrameView)
}
}
func customLayout() {
self.navigationController?.isNavigationBarHidden = false
self.removeNavBarLine()
self.setNavigation(title: "Scan QRCode", withTintColor: .willianPinhoOrange, barTintColor: .willianPinhoBlue, andAttributes: [NSAttributedStringKey.font: UIFont.openWorkSansWithType(withSize: 24, type: WorkSansType.light), NSAttributedStringKey.foregroundColor: UIColor.willianPinhoOrange], prefersLargeTitles: false)
}
func launchApp(decodedURL: String) {
if presentedViewController != nil {
return
}
if decodedURL.hasPrefix("https://gist.github.com/") {
let alert = Alert.showMessage(title: "Want to open this wonderful gist?", message: "Link of Gist: \(decodedURL)")
let confirmAction = UIAlertAction(title: "Of Course!", style: UIAlertActionStyle.default, handler: { (action) -> Void in
self.openViewControllerWithIdentifier(storyBoard: "Main", identifier: "GistViewController")
})
let cancelAction = UIAlertAction(title: "No, leave me alone!", style: UIAlertActionStyle.cancel, handler: nil)
alert.addAction(confirmAction)
alert.addAction(cancelAction)
present(alert, animated: true, completion: nil)
}
else {
let alert = Alert.showMessage(title: "Sorry!", message: "Maybe in the next version. \nThe developer didn't teach me how to open this kind of URL :(")
alert.addAction(Alert.addOkAction(alert: alert))
present(alert, animated: true, completion: nil)
}
}
}
extension ScanViewController: AVCaptureMetadataOutputObjectsDelegate {
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
// Check if the metadataObjects array is not nil and it contains at least one object.
if metadataObjects.count == 0 {
qrCodeFrameView?.frame = CGRect.zero
bottomLabel.text = "No QR Code detected"
return
}
// Get the metadata object.
let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
if supportedCodeTypes.contains(metadataObj.type) {
// If the found metadata is equal to the QR code then update the status label's text and set the bounds
let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
qrCodeFrameView?.frame = barCodeObject!.bounds
if metadataObj.stringValue != nil {
launchApp(decodedURL: metadataObj.stringValue!)
bottomLabel.text = metadataObj.stringValue
}
}
}
}
@willianpinho
Copy link
Author

Awesome comment!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment