카메라 세션을 설정할 때 Crashlytics에 이상한 충돌이 표시됩니다. stacktrace는 addInput 메소드에서 크래시가 발생했음을 보여줍니다.AVCaptureDeviceInput을 추가 할 때 AVCaptureSession에 충돌이 발생했습니다.
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
}
}
}
setupCamSession가있는 viewDidLoad에서 호출 viewWillAppear에서 runSession와 나는 또한 viewWillDisappear에서 stopSession 방법이있다. 카메라 세션과 관련된 모든 것이 백그라운드 직렬 대기열에 전달됩니다.
충돌이 100 % 발생하지 않으며 사용하는 장치에서 크래시를 재현 할 수 없습니다. 감사합니다.
보기로 이동하십시오. 적용 또는 표시합니다 .DidAppear –
왜? 나는 그것을 viewDidLoad()에 유지하는 것을 선호한다. 실제로 홈 화면에는 카메라보기가 있으며 홈 화면에서 여러 번보기 컨트롤러를 밀고 팝합니다. ViewWillAppear은 여러 번 호출되며 카메라 세션을 다시 설정할 때마다 호출됩니다. 현재는 카메라 세션 만 실행 중입니다. – ELKA
https://developer.apple.com/library/ios/samplecode/AVCam/Listings/AVCam_AAPLCameraViewController_m.html#//apple_ref/doc/uid/DTS40010112-AVCam_AAPLCameraViewController_m-DontLinkElementID_6에서 영감을 받았습니다. 그들은 viewDidLoad()에서 입력을 설정합니다. – ELKA