You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级iOS 18后AVCapturePhotoCaptureDelegate报sessionNotRunning错误

iOS 18 中 AVCaptureSession 显示运行但拍照报 AVError.sessionNotRunning (-11803) 错误

问题背景

我的相机捕获代码在iOS 18之前运行完全正常,封装拍照功能的PhotoCaptureManager类会在用户进入相机界面时懒加载初始化AVCaptureSession,在CameraViewController的viewDidAppear中启动会话,点击拍照按钮执行捕获逻辑。但升级到iOS 18后,点击拍照会抛出AVError.Code.sessionNotRunning错误,尽管captureSession.isRunning始终返回true,且photoOutput.captureReadiness状态为.ready。

相关代码片段

初始化 AVCaptureSession

lazy var captureSession: AVCaptureSession? = {
    let session = AVCaptureSession()
    session.automaticallyConfiguresApplicationAudioSession = false
    do {
        guard let videoDevice = self.currentVideoDevice else { return nil }
        let videoDeviceInput = try AVCaptureDeviceInput(device: videoDevice)
        guard session.canAddInput(videoDeviceInput) else { return nil}
        session.beginConfiguration()
        session.addInput(videoDeviceInput)
        session.addOutput(photoOutput)
        session.sessionPreset = .photo
        session.commitConfiguration()
        return session
    } catch {
        print(error)
        return nil
    }
}()

启动会话的逻辑

private func setupCameraPreview() {
    DispatchQueue.main.async {
        self.cameraPreview.videoPreviewLayer.session = self.cameraManager.capture.captureSession
        DispatchQueue.global(qos: .userInteractive).async { [weak self] in
            self?.cameraManager.capture.captureSession?.startRunning()
        }
    }
}

拍照触发逻辑

func takePicture(_ completion: @escaping (_ imageData: Data?) -> Void) {
    takePictureCompletion = completion
    let settings = AVCapturePhotoSettings()
    photoOutput.connection(with: AVMediaType.video)?.videoOrientation = currentVideoOrientation(by: UIDevice.current.orientation)
    photoOutput.capturePhoto(with: settings, delegate: self)
}

捕获结果处理

extension DefaultPhotoCaptureManager: AVCapturePhotoCaptureDelegate {

    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {

        if let error {
            print(error)
            return
        }

        guard let jpegData = photo.fileDataRepresentation() else { return }

        takePictureCompletion?(jpegData)
    }

    func photoOutput(_ output: AVCapturePhotoOutput, didCapturePhotoFor resolvedSettings: AVCaptureResolvedPhotoSettings) {
        print(resolvedSettings)
    }
}

错误信息

执行拍照时,didCapturePhotoFor方法打印的日志:

<<<< AVCapturePhotoOutput >>>> Fig assert: "hasFigCaptureSession" at bail (AVCapturePhotoOutput.m:529) - (err=0)
<AVCaptureResolvedPhotoSettings: 0x30163d4a0 uid:3 photo:{0x0} time:nan-nan>

didFinishProcessingPhoto返回的错误详情:

Optional

  • some : Error Domain=AVFoundationErrorDomain Code=-11803 UserInfo={AVErrorRecordingFailureDomainKey=3}

对应的错误码为AVError.Code.sessionNotRunning,但多次检查确认captureSession.isRunning为true,photoOutput.captureReadiness始终是.ready。

临时解决方案

在takePicture方法中添加iOS 18专属适配代码后,问题得到解决:

if #available(iOS 18.0, *) {
    photoOutput.maxPhotoQualityPrioritization = .speed
}

根据官方文档说明,运行时修改maxPhotoQualityPrioritization属性会触发会话重建,可能导致预览中断,但实际测试中并未出现预览中断的情况,反而解决了拍照报错的问题。

疑问

想知道iOS 18中引发这个问题的具体原因是什么?是否有其他开发者遇到过相同的问题?

内容的提问来源于stack exchange,提问作者Alex Sh.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 04:21:06