3
votes

I'm using this piece of code:

func capturePhoto(blockCompletion: @escaping blockCompletionCapturePhoto) {
    guard let connectionVideo  = self.stillCameraOutput.connection(withMediaType: AVMediaTypeVideo) else {
        blockCompletion(nil, nil)
        return
    }

    connectionVideo.videoOrientation = AVCaptureVideoOrientation.orientationFromUIDeviceOrientation(orientation: UIDevice.current.orientation)

    self.stillCameraOutput.captureStillImageAsynchronouslyFromConnection(connectionVideo) { (sampleBuffer: CMSampleBuffer!, err: NSError!) -> Void in
        if let err = err {
            blockCompletion(image: nil, error: err)
        }
        else {
            if let sampleBuffer = sampleBuffer, let dataImage = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer) {
                let image = UIImage(data: dataImage)
                blockCompletion(image: image, error: nil)
            }
            else {
                blockCompletion(image: nil, error: nil)
            }
        }
    }
}

It worked fine in Swift 2.0, but after conversion it's not working anymore. This line:

self.stillCameraOutput.captureStillImageAsynchronouslyFromConnection(connectionVideo) { (sampleBuffer: CMSampleBuffer!, err: NSError!) -> Void in 

is giving me the following error:

Cannot convert value of type '(CMSampleBuffer!, NSError!) -> Void' to expected argument type '((CMSampleBuffer?, Error?) -> Void)!'

I've already tried some things but can't get it solved. Hopefully someone can help me.

2
I think that NSError got renamed to Error in Swift 3. Simply remove NS and it should be fine. Did you migrate your code? It'd be strange if it didn't catch that. - Losiowaty

2 Answers

3
votes

What the error

Cannot convert value of type '(CMSampleBuffer!, NSError!) -> Void' to expected argument type '((CMSampleBuffer?, Error?) -> Void)!'

basically says is that your argument is of the wrong type ((CMSampleBuffer!, NSError!) -> Void) while it should be of the type ((CMSampleBuffer?, Error?) -> Void)!.

To achieve this, try using this code, it should automatically make your block conform to the right type:

self.stillCameraOutput.captureStillImageAsynchronouslyFromConnection(connectionVideo) { sampleBuffer, error in
    //do stuff with your sample buffer, don't forget to handle errors
}

It looks like a weird type but I think it's a little error Apple made somewhere while migrating this code from ObjC to Swift 1 to Swift 2 to Swift 3.
I haven't tested this code, but I think it should work, let me know if it actually did!

2
votes

In swift 3 that command changed!

from:

captureStillImageAsynchronouslyFromConnection

to:

captureStillImageAsynchronously

so try this code:

self.stillCameraOutput?.captureStillImageAsynchronously(from: connectionVideo, completionHandler: {
         (sampleBuffer, error) in
  // do your stuff here
}