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

如何将VNDocumentCameraViewControllerDelegate适配Swift 6并发模型

Swift 6下适配VNDocumentCameraViewControllerDelegate的并发问题解决方案

针对你遇到的Swift 6并发模型适配问题,以下是可行的解决方案:

核心修改思路

避开类级别@MainActor导致的协议一致性冲突,同时通过显式切换主Actor上下文处理UI操作,再通过Sendable合规性解决单例的并发安全问题。

修改后的完整代码

fileprivate class DocumentScanDelegate: NSObject, VNDocumentCameraViewControllerDelegate, @unchecked Sendable {
  
  static let shared = DocumentScanDelegate()

  var compressionQuality: CGFloat = 1
  var onScanSuccess: (UIImage) -> Void = { _ in }
  
  func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
    MainActor.run {
      controller.dismiss(animated: true)
      
      guard scan.pageCount >= 1 else { return }
      let lastPage = scan.imageOfPage(at: scan.pageCount - 1)
      let compressed = lastPage.compressed(quality: self.compressionQuality)
      self.onScanSuccess(compressed)
    }
  }
  
  func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFailWithError error: Error) {
    MainActor.run {
      controller.dismiss(animated: true)
    }
  }
  
  func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
    MainActor.run {
      controller.dismiss(animated: true)
    }
  }
}

关键修改说明

  1. 添加@unchecked Sendable合规性
    由于类继承自NSObject(未原生遵循Sendable),但我们可以保证类内可变状态(compressionQuality、onScanSuccess)的访问仅在主Actor上下文执行,因此用@unchecked Sendable标记类,解决单例shared的并发安全错误。

  2. 用MainActor.run包裹UI操作
    VNDocumentCameraViewControllerDelegate的回调方法可能在后台线程触发,而dismiss是UIKit的主Actor隔离方法,必须在主线程执行。通过MainActor.run将所有UI相关逻辑切换到主Actor上下文,既解决了跨Actor调用的错误,又避免了类级别@MainActor与协议非隔离要求的冲突。

  3. 规避VNDocumentCameraScan的Sendable问题
    虽然VNDocumentCameraScan未遵循Sendable,但我们仅在回调方法的局部作用域内读取它的属性,且所有访问都被包裹在MainActor.run中,不会产生并发访问风险,Swift 6会认可这种用法。

内容的提问来源于stack exchange,提问作者OMGPOP

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:57:19