Ich habe einen seltsamen Absturz bei Crashlytics beim Einrichten einer Kamera-Sitzung. Der Stacktrace zeigt, dass der Absturz bei der Methode addInput aufgetreten ist.Absturz in AVCaptureSession beim Hinzufügen eines AVCaptureDeviceInput
func setupCamSession(){
self.captureSession = AVCaptureSession()
self.cameraView.setSession(self.captureSession)
self.sessionQueue = dispatch_queue_create("com.myapp.camera_queue", DISPATCH_QUEUE_SERIAL)
self.setupResult = .Success
switch AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo){
case .Authorized:
break //already we set it to success
case .NotDetermined:
// The user has not yet been presented with the option to grant video access.
// We suspend the session queue to delay session setup until the access request has completed
dispatch_suspend(self.sessionQueue)
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (granted) -> Void in
if (!granted) {
self.setupResult = .CameraNotAuthorized
}
dispatch_resume(self.sessionQueue)
})
default:
self.setupResult = .CameraNotAuthorized
}
dispatch_async(self.sessionQueue){
if self.setupResult != .Success{
return
}
//link input to captureSession
guard let videoDevice = self.deviceWithMediaType(AVMediaTypeVideo, position: AVCaptureDevicePosition.Back) else{
AppLog("Video Device Unavailable")
self.setupResult = .SessionConfigurationFailed
return
}
var videoDeviceInput: AVCaptureDeviceInput!
do {
videoDeviceInput = try AVCaptureDeviceInput(device: videoDevice)
}catch {
AppLog("Could not create video device input")
}
/////////////////////////////////////////////////////
self.captureSession.beginConfiguration()
if self.captureSession.canAddInput(videoDeviceInput){
self.captureSession.addInput(videoDeviceInput)
self.videoDeviceInput = videoDeviceInput
self.videoDevice = videoDevice
dispatch_async(dispatch_get_main_queue()){
//update the cameraView layer on the main thread
let previewLayer : AVCaptureVideoPreviewLayer = self.cameraView.layer as! AVCaptureVideoPreviewLayer
previewLayer.connection.videoOrientation = AVCaptureVideoOrientation(ui:UIApplication.sharedApplication().statusBarOrientation)
}
}else{
AppLog("Could not add video device input to the session")
self.setupResult = .SessionConfigurationFailed
}
//link output to captureSession
let stillImageOutput = AVCaptureStillImageOutput()
if self.captureSession.canAddOutput(stillImageOutput){
self.captureSession.addOutput(stillImageOutput)
self.stillImageOutput = stillImageOutput
stillImageOutput.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]
}else{
AppLog("Could not add still image output to the session")
self.setupResult = .SessionConfigurationFailed
}
self.captureSession.commitConfiguration()
/////////////////////////////////////////////////////
}
}
func runSession(){
dispatch_async(self.sessionQueue){
switch self.setupResult!{
case .Success:
self.videoDeviceInput!.device.addObserver(self, forKeyPath: "adjustingFocus", options: NSKeyValueObservingOptions.New, context: nil)
self.captureSession.addObserver(self, forKeyPath: "running", options: [.New], context: &SessionRunningContext)
self.captureSession.startRunning()
self.captureSessionRunning = self.captureSession.running
if !self.captureSessionRunning {
self.captureSession.removeObserver(self, forKeyPath: "running", context: &SessionRunningContext)
self.videoDeviceInput?.device?.removeObserver(self, forKeyPath: "adjustingFocus", context: nil)
}
default:
//Handle errors.
}
}
func stopCaptureSession(){
dispatch_async(self.sessionQueue){
if self.setupResult == .Success{
if self.captureSessionRunning{
self.captureSession.stopRunning()
self.videoDeviceInput?.device?.removeObserver(self, forKeyPath: "adjustingFocus", context: nil)
self.captureSession.removeObserver(self, forKeyPath: "running", context: &SessionRunningContext)
}
self.captureSessionRunning = false
}
}
}
Die setupCamSession in viewDidLoad, die runSession in viewWillAppear genannt und ich habe auch eine stopSession Methode in viewWillDisappear. Alles, was mit der Kamerasitzung zusammenhängt, wird in einer seriellen Warteschlange im Hintergrund ausgelöst.
Der Absturz passiert nicht 100% der Zeit und ich kann den Absturz nicht auf dem Gerät reproduzieren, das ich benutze. Danke
move it zu viewWillAppear oder viewDidAppear –
Warum? Ich bevorzuge es in viewDidLoad() zu halten. In der Tat hat der Home-Bildschirm die Kamera-Ansicht und wir schieben und knallen View-Controller viele Male auf dem Home-Bildschirm. So wird ViewWillAppear mehrmals aufgerufen und jedes Mal wird die Kamera-Session neu eingerichtet. Derzeit wird nur die Kamerasitzung ausgeführt. – ELKA
Ich wurde von https://developer.apple.com/library/ios/samplecode/AVCam/Listings/AVCam_AAPLCameraViewController_m.html#//apple_ref/doc/uid/DTS40010112-AVCam_AAPLCameraViewController_m-DontLinkElementID_6 inspiriert. Sie konfigurieren die Eingabe in viewDidLoad() – ELKA