视图通过导航控制器解散后,应用程序崩溃了吗?

时间:2018-02-15 21:36:13

标签: ios swift avfoundation unwind-segue

在导航控制器中关闭视图后,应用程序崩溃是可以在导航控制器展开期间重新加载单元格。

如果点击了翻转按钮,则相机会发生变化,但是当点按相机按钮时,应用程序会因此错误而崩溃

  

没有有效且已启用的视频连接

可能出现的问题

import UIKit
import AVFoundation


protocol previewSegueDelegate {
func previewSegueDelegate(image:UIImage,device:AVCaptureDevice)
}

class MainCameraCollectionViewCell: UICollectionViewCell {

var gdelegate: gestureDelegate?
var pdelegate: previewSegueDelegate?


@IBOutlet weak var myView: UIView!

var captureSession = AVCaptureSession()
private var sessionQueue: DispatchQueue!
var captureConnection = AVCaptureConnection()
var currentCamera: AVCaptureDevice?

var photoOutPut: AVCapturePhotoOutput?

var cameraPreviewLayer: AVCaptureVideoPreviewLayer?

var image: UIImage?

 var usingFrontCamera = false

override func awakeFromNib() {
    super.awakeFromNib()
    setupCaptureSession()
    setupDevice()
    setupInput()
    setupPreviewLayer()
    startRunningCaptureSession()
    print("Inside of camera cell")
}

func setupCaptureSession(){
    captureSession.sessionPreset = AVCaptureSession.Preset.photo
    sessionQueue = DispatchQueue(label: "session queue")
}

func setupDevice(usingFrontCamera:Bool = false){
    sessionQueue.async {
    let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)
    let devices = deviceDiscoverySession.devices

    for device in devices{
        if usingFrontCamera && device.position == AVCaptureDevice.Position.front {
            self.currentCamera = device
        } else if device.position == AVCaptureDevice.Position.back {
            self.currentCamera = device
        }
    }
    }
}

func setupInput() {
    sessionQueue.async {
        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: self.currentCamera!)
            if self.captureSession.canAddInput(captureDeviceInput) {
                self.captureSession.addInput(captureDeviceInput)
            }
            self.photoOutPut = AVCapturePhotoOutput()
            self.photoOutPut?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
            if self.captureSession.canAddOutput(self.photoOutPut!) {
                self.captureSession.addOutput(self.photoOutPut!)
            }
        } catch {
            print(error)
        }
    }
}
func setupPreviewLayer(){
    cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
    cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
    cameraPreviewLayer?.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
    self.layer.insertSublayer(cameraPreviewLayer!, at: 0)
}

func startRunningCaptureSession(){
    captureSession.startRunning()
}


@IBAction func cameraButton_TouchUpInside(_ sender: Any) {
    let settings = AVCapturePhotoSettings()
    photoOutPut?.capturePhoto(with: settings, delegate: self as AVCapturePhotoCaptureDelegate)
    print("camera button touched")
}

@IBAction func FlipThe_camera(_ sender: UIButton) {
print("Flip Touched")
    captureSession.beginConfiguration()
    if let inputs = captureSession.inputs as? [AVCaptureDeviceInput] {
        for input in inputs {
            captureSession.removeInput(input)
        }
    }
    usingFrontCamera = !usingFrontCamera
    setupCaptureSession()
    setupDevice(usingFrontCamera: usingFrontCamera)
    setupInput()
    captureSession.commitConfiguration()
    startRunningCaptureSession()
}

 }


  extension MainCameraCollectionViewCell: 
  AVCapturePhotoCaptureDelegate{
func photoOutput(_ output: AVCapturePhotoOutput, 
  didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    if let imageData = photo.fileDataRepresentation(){
        print(imageData)
        image = UIImage(data: imageData)
        if(self.image == nil){
            print("The image is empty")
        }
        pdelegate?.previewSegueDelegate(image: self.image!, device: 
      currentCamera!)
      }
    }
   }

1 个答案:

答案 0 :(得分:0)

我相信你需要使用:

captureSesssion.sessionPreset = AVCaptureSessionPresetPhoto

答案由Aleksey Timoshchenko发现HERE

    import UIKit
import AVFoundation

class ViewController: UIViewController, AVCapturePhotoCaptureDelegate {

var captureSesssion : AVCaptureSession!
var cameraOutput : AVCapturePhotoOutput!
var previewLayer : AVCaptureVideoPreviewLayer!

@IBOutlet weak var capturedImage: UIImageView!
@IBOutlet weak var previewView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()
    captureSesssion = AVCaptureSession()
    captureSesssion.sessionPreset = AVCaptureSessionPresetPhoto
    cameraOutput = AVCapturePhotoOutput()

    let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

    if let input = try? AVCaptureDeviceInput(device: device) {
        if (captureSesssion.canAddInput(input)) {
            captureSesssion.addInput(input)
            if (captureSesssion.canAddOutput(cameraOutput)) {
                captureSesssion.addOutput(cameraOutput)
                previewLayer = AVCaptureVideoPreviewLayer(session: captureSesssion)
                previewLayer.frame = previewView.bounds
                previewView.layer.addSublayer(previewLayer)
                captureSesssion.startRunning()
            }
        } else {
            print("issue here : captureSesssion.canAddInput")
        }
    } else {
        print("some problem here")
    }
}

// Take picture button
@IBAction func didPressTakePhoto(_ sender: UIButton) {
    let settings = AVCapturePhotoSettings()
    let previewPixelType = settings.availablePreviewPhotoPixelFormatTypes.first!
    let previewFormat = [
         kCVPixelBufferPixelFormatTypeKey as String: previewPixelType,
         kCVPixelBufferWidthKey as String: 160,
         kCVPixelBufferHeightKey as String: 160
    ]
    settings.previewPhotoFormat = previewFormat
    cameraOutput.capturePhoto(with: settings, delegate: self)
}

// callBack from take picture
func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {

    if let error = error {
        print("error occure : \(error.localizedDescription)")
    }

    if  let sampleBuffer = photoSampleBuffer,
        let previewBuffer = previewPhotoSampleBuffer,
        let dataImage =  AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer:  sampleBuffer, previewPhotoSampleBuffer: previewBuffer) {
        print(UIImage(data: dataImage)?.size as Any)

        let dataProvider = CGDataProvider(data: dataImage as CFData)
        let cgImageRef: CGImage! = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent)
        let image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: UIImageOrientation.right)

        self.capturedImage.image = image
    } else {
        print("some error here")
    }
}

// This method you can use somewhere you need to know camera permission   state
func askPermission() {
    print("here")
    let cameraPermissionStatus =  AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)

    switch cameraPermissionStatus {
    case .authorized:
        print("Already Authorized")
    case .denied:
        print("denied")

        let alert = UIAlertController(title: "Sorry :(" , message: "But  could you please grant permission for camera within device settings",  preferredStyle: .alert)
        let action = UIAlertAction(title: "Ok", style: .cancel,  handler: nil)
        alert.addAction(action)
        present(alert, animated: true, completion: nil)

    case .restricted:
        print("restricted")
    default:
        AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: {
            [weak self]
            (granted :Bool) -> Void in

            if granted == true {
                // User granted
                print("User granted")
 DispatchQueue.main.async(){
            //Do smth that you need in main thread   
            } 
            }
            else {
                // User Rejected
                print("User Rejected")

DispatchQueue.main.async(){
            let alert = UIAlertController(title: "WHY?" , message:  "Camera it is the main feature of our application", preferredStyle: .alert)
                let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
                alert.addAction(action)
                self?.present(alert, animated: true, completion: nil)  
            } 
            }
        });
    }
}
}