最近几个版本老出现这个问题:Inconsistent state
Inconsistent state
一、之前处理的方法
- 1、对于打断的模式进行监听,进行处理
[[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)sessionWasInterrupted:(NSNotification*)notification {
self.takePhotoView.userActionEnable = NO;
}
- (void)sessionInterruptionEnded:(NSNotification*)notification {
self.takePhotoView.userActionEnable = YES;
}
- 2、对于无效的 connection
AVCaptureConnection *connection = [self.imageOutput connectionWithMediaType:AVMediaTypeVideo];
if (!connection || !connection.enabled || !connection.active) {
return;
}
二、处理的结果
发现如上解决后,没有真正的解决,解决的是另一种情况: Inactive/invalid connection passed Inactive/invalid connection passed
线上时不时还是有这个崩溃发生的
三、再次回归
依然有这个问题,那就只能继续再寻找
突然发现,我们用的是AVCaptureStillImageOutput
API_DEPRECATED("Use AVCapturePhotoOutput instead.", macos(10.7, 10.15), ios(4.0, 10.0)) API_UNAVAILABLE(tvos) __WATCHOS_PROHIBITED
@interface AVCaptureStillImageOutput : AVCaptureOutput
而且该线上奔溃都是发生在 iOS 11 以上的,所以在没有判断出到底啥错的情况下,猜测是其API 兼容问题,对此采用 AVCapturePhotoOutput
API_AVAILABLE(macos(10.15), ios(10.0), macCatalyst(14.0)) API_UNAVAILABLE(tvos) __WATCHOS_PROHIBITED
@interface AVCapturePhotoOutput : AVCaptureOutput
So, 做了下版本判断的:
/// 拍照动作
- (void)takePhoto {
if (@available(iOS 11.0, *)) {
[self takePhotoOutput];
} else {
[self takeStillImageOutput];
}
}
// iOS 11 以上 获取图片
- (void)takePhotoOutput API_AVAILABLE(ios(11.0)) {
self.takePhotoView.userActionEnable = NO;
AVCapturePhotoSettings *settings = [AVCapturePhotoSettings photoSettings];
[self.photoOutput capturePhotoWithSettings:settings delegate:self];
}
// iOS 11 以上 获取图片的回调
- (void)captureOutput:(AVCapturePhotoOutput *)output didFinishProcessingPhoto:(AVCapturePhoto *)photo error:(NSError *)error API_AVAILABLE(ios(11.0)) {
if (error || !photo) {
DLog(@"未取到拍摄的图片");
self.takePhotoView.userActionEnable = YES;
return;
}
CGImageRef cgImage = [photo CGImageRepresentation];
// 需要调整下方向
UIImageOrientation imgOrientation = UIImageOrientationRight;
UIImage *image = [[UIImage alloc] initWithCGImage:cgImage scale:1.0f orientation:imgOrientation];
[self dealCaptureOutputImage:image];
}
// iOS 10 以下 获取图片
- (void)takeStillImageOutput {
self.takePhotoView.userActionEnable = NO;
AVCaptureConnection *connection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
if (!connection || !connection.enabled || !connection.active) {
DLog(@"拍照失败!");
self.takePhotoView.userActionEnable = YES;
return;
}
if ([connection isVideoStabilizationSupported]) {
connection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto;
}
@weakify(self);
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef _Nullable imageDataSampleBuffer, NSError * _Nullable error) {
@strongify(self);
if (imageDataSampleBuffer == nil) {
DLog(@"未取到拍摄的图片");
self.takePhotoView.userActionEnable = YES;
return;
}
//获取拍摄的图片
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [UIImage imageWithData:imageData];
[self dealCaptureOutputImage:image];
}];
}
此处直接用 API_AVAILABLE(ios(11.0) 判断,而没有用 iOS 10 是因为 AVCapturePhotoOutput 的回调发现在 iOS 10 到 iOS 11 之间还做了一次处理,于是直接调用了 iOS 11 的
- (void)captureOutput:(AVCapturePhotoOutput *)output didFinishProcessingRawPhotoSampleBuffer:(nullable CMSampleBufferRef)rawSampleBuffer previewPhotoSampleBuffer:(nullable CMSampleBufferRef)previewPhotoSampleBuffer resolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings bracketSettings:(nullable AVCaptureBracketedStillImageSettings *)bracketSettings error:(nullable NSError *)error
API_DEPRECATED_WITH_REPLACEMENT("-captureOutput:didFinishProcessingPhoto:error:", ios(10.0, 11.0)) API_UNAVAILABLE(macos) API_UNAVAILABLE(tvos);
- (void)captureOutput:(AVCapturePhotoOutput *)output didFinishProcessingPhoto:(AVCapturePhoto *)photo error:(nullable NSError *)error
API_AVAILABLE(ios(11.0), macCatalyst(14.0)) API_UNAVAILABLE(tvos);
经过版本判断后,最近一个月暂时木有重现该问题。
这几天刚好 AppStore 有一个 BUG,提交版本后默认成最低支持 iOS 11 的版本。
虽说这个问题今天苹果已经修复,但我个人感觉偶尔来一次,也有好处,强行让用户升级一波了,这样我们就不要去兼容 iOS 9 iOS 10 的用户啦,哈哈哈哈
网友评论