0

I am new to iOS development and I am trying to follow the following tutorial to learn how to capture images and then save them on a server for my purposes:

https://medium.com/@rizwanm/swift-camera-part-2-c6de440a9404

The tutorial is great and I am only initializing the camera and trying to snap the image (not doing the QR part). Unfortunately, when I hit the 'capture' button, the image is not being taken or saved in my gallery and I am not able to understand why. I use Xcode 8.3 and I am running iOS 10.3 on my iPhone.

I have connected the button with the view controller and called it in the function onTapTakePhoto as shown in the code below. Please advise as to why this might be happening.

import UIKit
import AVFoundation

class ViewController: UIViewController {
    @IBOutlet weak var previewView: UIView!
    @IBOutlet weak var CaptureButton: UIButton!

    //helps transfer data between one or more input device like camera
    var captureSession: AVCaptureSession?
    //instance variable
    var capturePhotoOutput: AVCapturePhotoOutput? //capturePhotoOutput will help us snap a live photo

    //helps render the camera view finder in ViewController
    var videoPreviewLayer: AVCaptureVideoPreviewLayer?

    override func viewDidLoad() {
        super.viewDidLoad()

        CaptureButton.layer.cornerRadius = CaptureButton.frame.size.width / 2
        CaptureButton.clipsToBounds = true

        //set up camera here
        let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

        // get an instance of the AVCAptureDevicenput
        // serves as a middle man to attach input device to capture device
        // chance the input device unavailable so wrap in do catch

        do {
            // Get an instance of the AVCaptureDeviceInput class using the previous deivce object
             let input = try AVCaptureDeviceInput(device: captureDevice)
            // Initialize the captureSession object
            captureSession = AVCaptureSession()

            // Set the input devcie on the capture session
            captureSession?.addInput(input)

            //set up preview view to see live feed
            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
            videoPreviewLayer?.frame = view.layer.bounds
            previewView.layer.addSublayer(videoPreviewLayer!)

            // finally start the capture session
            captureSession?.startRunning()

            // get an instance of AVCapturePhotoOutput class
            capturePhotoOutput = AVCapturePhotoOutput()
            capturePhotoOutput?.isHighResolutionCaptureEnabled = true
            //set the outut on the capture session
            captureSession?.addOutput(capturePhotoOutput)

        } catch {
            print (error)
            return
        }
    }

    @IBAction func onTapTakePhoto(_ sender: UIButton) {
        // Make sure capturePhotoOutput is valid
        guard let capturePhotoOutput = self.capturePhotoOutput else { return }

        // Get an instance of AVCapturePhotoSettings class
        let photoSettings = AVCapturePhotoSettings()

        // Set photo settings for our need
        photoSettings.isAutoStillImageStabilizationEnabled = true
        photoSettings.isHighResolutionPhotoEnabled = true
        photoSettings.flashMode = .auto

        // Call capturePhoto method by passing our photo settings and a delegate implementing AVCapturePhotoCaptureDelegate
        capturePhotoOutput.capturePhoto(with: photoSettings, delegate: self)
    }
}

// to get the captured image
extension ViewController : AVCapturePhotoCaptureDelegate {
    func capture(_ captureOutput: AVCapturePhotoOutput,
                 didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?,
                 previewPhotoSampleBuffer: CMSampleBuffer?,
                 resolvedSettings: AVCaptureResolvedPhotoSettings,
                 bracketSettings: AVCaptureBracketedStillImageSettings?,
                 error: Error?) {
        // Make sure we get some photo sample buffer
        guard error == nil,
            let photoSampleBuffer = photoSampleBuffer else {
                print("Error capturing photo: \(String(describing: error))")
                return
        }

        // Convert photo same buffer to a jpeg image data by using AVCapturePhotoOutput
        guard let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) else {
            return
        }

        // Initialise an UIImage with our image data
        let capturedImage = UIImage.init(data: imageData , scale: 1.0)
        if let image = capturedImage {
            // Save our captured image to photos album
            UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
        }
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Veejay
  • 397
  • 3
  • 10
  • 17

4 Answers4

0

One thing that you should check is that, if you have added the permission in the info.plist file to access the camera.

You have to make a key-value entry for the key

Privacy - Photo Library Usage Description

(if you are using the gallery)

and

Privacy - Camera Usage Description

for using the camera itself.

Refer to this for more details.

If it doesn't work, put a debugger on the click action of the button and check the code flow. If the debugger is not hit after pressing the button, there could be an issue with the button action outlet, try to remake the outlet action.

Umar Farooque
  • 2,049
  • 21
  • 32
0

First of all with the help of break points, check which section of your code is not being executed.There might be some problem related to your button connection.

OR Try this one https://www.youtube.com/watch?v=994Hsi1zs6Q

OR this one in Objective-C https://github.com/omergul/LLSimpleCamera

S_J
  • 35
  • 1
  • 9
0

Thank you for the answers :)

The problem was a missing connection to my action button code from the story board. Feels like such a silly mistake in retrospect

Veejay
  • 397
  • 3
  • 10
  • 17
0
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

        if (info[UIImagePickerControllerOriginalImage] as? UIImage) != nil {
          }
        dismiss(animated: true, completion:
            {
               // write your set image code for UIButton is here.
            })
    }
jbchitaliya
  • 211
  • 2
  • 13