解决使用AVCaptureSession拍照闪退的问题

2,931 阅读1分钟

近期在bug后台收到一条NSInternalInconsistencyException导致闪退的记录。

出错堆栈如下:-[AVCaptureStillImageOutput captureStillImageAsynchronouslyFromConnection:completionHandler:] Inconsistent state

同时注意到该错误全部发生在iPad上。

最后查到原因是在iPad上开启了画中画的情况下,使用AVCaptureSession拍照由于session处于被interrupt的状态,所以会导致闪退。还有其他的原因例如打电话,闹铃,处在分屏模式下等。

解决办法:在session startRunning前添加AVCaptureSessionWasInterrupted通知的观察。样例代码如下:


#pragma mark - Session Notifications

- (void) addObservers
{
    /*
     A session can only run when the app is full screen. It will be interrupted
     in a multi-app layout, introduced in iOS 9, see also the documentation of
     AVCaptureSessionInterruptionReason. Add observers to handle these session
     interruptions and show a preview is paused message. See the documentation
     of AVCaptureSessionWasInterruptedNotification for other interruption reasons.
     */
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionWasInterrupted:) name:AVCaptureSessionWasInterruptedNotification object:self.session];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionInterruptionEnded:) name:AVCaptureSessionInterruptionEndedNotification object:self.session];
}

- (void) removeObservers
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
}


- (void) sessionWasInterrupted:(NSNotification*)notification
{
    AVCaptureSessionInterruptionReason reason = [notification.userInfo[AVCaptureSessionInterruptionReasonKey] integerValue];
    NSLog(@"Capture session was interrupted with reason %ld", (long)reason);
    
    //在此禁止掉拍照功能,同时添加提醒
    if (reason == AVCaptureSessionInterruptionReasonAudioDeviceInUseByAnotherClient ||
        reason == AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient) {
       
    }
    else if (reason == AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps) {
       
        
    }
    else if (@available(iOS 11.1, *)) {
        if (reason == AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableDueToSystemPressure) {
            
        }
    } else {
        // Fallback on earlier versions
    }
}

- (void) sessionInterruptionEnded:(NSNotification*)notification
{
   //在此可以恢复拍照功能
}

具体可以查看苹果的样例代码