Потерянное соединение с iPhone X в процессе захвата фотографии с задней камеры на Xcode 8.3 и iOS 10.3.2

В моем приложении есть функция захвата фотографий как с передней, так и с редкой камеры. Обе камеры работают должным образом на ios 10.2.1 и менее, но если я запускаю приложение на iOS 10.3.2 и снимаю фотографию с передней камеры, все работает отлично, но пока я пытаюсь сделать снимок с редкой или задней камеры, приложение вылетает с ошибкой "Потерянное соединение с iPhone X". Я погуглил и обнаружил, что эта проблема возникает, когда размер изображения больше, и это проблема памяти. Но я также попытался решить проблему, изменив размер фотографии. Не могли бы вы указать мне, что мне не хватает.

Примечание:- Фотосъемка также выполняется медленнее, чем при обычной работе камеры.

Исходный код

class CameraLibrary: NSObject {

weak var delegate: CameraLibraryDelegate?

var session: AVCaptureSession!

var sessionQueue: DispatchQueue!
var stillImageOutput: AVCaptureStillImageOutput?
init(sender: AnyObject) {
    super.init()
    self.delegate = sender as? CameraLibraryDelegate
    self.setObservers()
    self.initializeSession()
}

deinit {
    self.removeObservers()
}

// MARK: Session

func initializeSession() {
    self.session = AVCaptureSession()
    self.session.sessionPreset = AVCaptureSessionPresetPhoto
    self.sessionQueue = DispatchQueue(label: "camera session", attributes: [])

    self.sessionQueue.async {
        self.session.beginConfiguration()
        self.addVideoInput()
        self.addStillImageOutput()
        self.session.commitConfiguration()

        DispatchQueue.main.async {
            NSLog("Session initialization did complete")
            self.delegate?.cameraSessionConfigurationDidComplete()
        }
    }
}

func startCamera() {
    self.sessionQueue.async {
        self.session.startRunning()
    }
}

func stopCamera() {
    self.sessionQueue.async {
        self.session.stopRunning()
    }
}

func captureStillImage(_ completed: @escaping (_ image: UIImage?) -> Void) {
    if let imageOutput = self.stillImageOutput {
        self.sessionQueue.async(execute: { () -> Void in

            var videoConnection: AVCaptureConnection?
            for connection in imageOutput.connections {
                let c = connection as! AVCaptureConnection

                for port in c.inputPorts {
                    let p = port as! AVCaptureInputPort
                    if p.mediaType == AVMediaTypeVideo {
                        videoConnection = c;
                        break
                    }
                }

                if videoConnection != nil {
                    break
                }
            }

            if videoConnection != nil {
                imageOutput.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (imageSampleBuffer: CMSampleBuffer!, error) -> Void in
                    let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
                    let image: UIImage? = UIImage(data: imageData!)!

                    //DispatchQueue.main.async {
                        completed(image)

                    //}
                })
            } else {
                DispatchQueue.main.async {
                    completed(nil)
                }
            }
       })
    } else {
        completed(nil)
    }
}
func checkCameraPermisson() -> Void {
    if AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) ==  AVAuthorizationStatus.authorized{
        print("Already Authorized")
    }
    else{
        AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (granted :Bool) -> Void in
            if granted == true{
                print("User granted")
            }
            else{
                NotificationCenter.default.post(name: Notification.Name(rawValue: "CameraAccessDenied"), object: nil)

            }
        });
    }

}

// MARK: Configuration

func addVideoInput() {

    if let inputs = self.session.inputs as? [AVCaptureDeviceInput] {
        for input in inputs {
            self.session.removeInput(input)
            self.session.addInput(input)
        }
    }

}

func addStillImageOutput() {
    stillImageOutput = AVCaptureStillImageOutput()
    stillImageOutput?.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]

    if self.session.canAddOutput(stillImageOutput) {
        session.addOutput(stillImageOutput)
    }
}


func deviceWithMediaTypeWithPosition(_ mediaType: NSString, position: AVCaptureDevicePosition) -> AVCaptureDevice {
    let devices: NSArray = AVCaptureDevice.devices(withMediaType: mediaType as String)! as NSArray
    var captureDevice: AVCaptureDevice = devices.firstObject as! AVCaptureDevice
    for device in devices {
        let d = device as! AVCaptureDevice
        if d.position == position {
            captureDevice = d

            break;

        }
    }
    return captureDevice
}

// MARK: Observers

func setObservers() {
    NotificationCenter.default.addObserver(self, selector: #selector(CameraLibrary.sessionDidStart(_:)), name: NSNotification.Name.AVCaptureSessionDidStartRunning, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(CameraLibrary.sessionDidStop(_:)), name: NSNotification.Name.AVCaptureSessionDidStopRunning, object: nil)
}

func removeObservers() {
    NotificationCenter.default.removeObserver(self)
}

func sessionDidStart(_ notification: Notification) {
    DispatchQueue.main.async {
        NSLog("Session did start")
        self.delegate?.cameraSessionDidBegin()
    }
}

func sessionDidStop(_ notification: Notification) {
    DispatchQueue.main.async {
        NSLog("Session did stop")
        self.delegate?.cameraSessionDidStop()
    }
}

0 ответов

Другие вопросы по тегам