Enhance ScannerViewModel to improve camera permission handling and capture session setup. Update logging messages for clarity and add retry logic for starting the scanning session. Ensure immediate scanning initiation after session setup, enhancing user experience and reliability.

main
v504 1 year ago
parent 81b2c74846
commit c350669bba

@ -27,9 +27,10 @@ class ScannerViewModel: NSObject, ObservableObject, AVCaptureMetadataOutputObjec
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized:
logInfo("✅ 相机权限已授权", className: "ScannerViewModel")
logInfo("✅ 相机权限已授权,立即设置捕获会话", className: "ScannerViewModel")
cameraAuthorizationStatus = .authorized
setupCaptureSession()
// setupCaptureSession 现在会自动启动扫描
case .notDetermined:
logInfo("❓ 相机权限未确定,请求权限", className: "ScannerViewModel")
@ -51,9 +52,10 @@ class ScannerViewModel: NSObject, ObservableObject, AVCaptureMetadataOutputObjec
AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in
DispatchQueue.main.async {
if granted {
logInfo("✅ 相机权限请求成功", className: "ScannerViewModel")
logInfo("✅ 相机权限请求成功,立即设置捕获会话", className: "ScannerViewModel")
self?.cameraAuthorizationStatus = .authorized
self?.setupCaptureSession()
// setupCaptureSession 现在会自动启动扫描
} else {
logWarning("❌ 相机权限请求被拒绝", className: "ScannerViewModel")
self?.cameraAuthorizationStatus = .denied
@ -78,15 +80,25 @@ class ScannerViewModel: NSObject, ObservableObject, AVCaptureMetadataOutputObjec
func refreshCameraPermission() {
logInfo("🔍 重新检查相机权限状态", className: "ScannerViewModel")
// 先停止当前扫描
if captureSession?.isRunning == true {
stopScanning()
}
// 重新检查权限
checkCameraPermission()
}
// MARK: - 相机设置
private func setupCaptureSession() {
logInfo("🔧 开始设置捕获会话", className: "ScannerViewModel")
captureSession = AVCaptureSession()
guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else {
logError("❌ 无法获取视频设备", className: "ScannerViewModel")
showAlert = true
return
}
@ -99,13 +111,16 @@ class ScannerViewModel: NSObject, ObservableObject, AVCaptureMetadataOutputObjec
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
} catch {
logError("❌ 创建视频输入失败: \(error.localizedDescription)", className: "ScannerViewModel")
showAlert = true
return
}
if captureSession.canAddInput(videoInput) {
captureSession.addInput(videoInput)
logInfo("✅ 成功添加视频输入", className: "ScannerViewModel")
} else {
logError("❌ 无法添加视频输入", className: "ScannerViewModel")
showAlert = true
return
}
@ -117,10 +132,19 @@ class ScannerViewModel: NSObject, ObservableObject, AVCaptureMetadataOutputObjec
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [.qr, .ean8, .ean13, .code128, .code39, .upce, .pdf417, .aztec]
logInfo("✅ 成功添加元数据输出", className: "ScannerViewModel")
} else {
logError("❌ 无法添加元数据输出", className: "ScannerViewModel")
showAlert = true
return
}
logInfo("✅ 捕获会话设置完成,准备启动扫描", className: "ScannerViewModel")
// 设置完成后立即启动扫描
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
self?.startScanning()
}
}
// MARK: - 扫描控制
@ -128,23 +152,70 @@ class ScannerViewModel: NSObject, ObservableObject, AVCaptureMetadataOutputObjec
func startScanning() {
logInfo("🔄 开始扫描", className: "ScannerViewModel")
// 检查相机权限
guard cameraAuthorizationStatus == .authorized else {
logWarning("❌ 相机权限未授权,无法启动扫描", className: "ScannerViewModel")
return
}
// 检查捕获会话是否已设置
guard captureSession != nil else {
logWarning("⚠️ 捕获会话未设置,重新设置", className: "ScannerViewModel")
setupCaptureSession()
return
}
// 检查会话是否已经在运行
if captureSession?.isRunning == true {
if captureSession.isRunning {
logInfo("ℹ️ 扫描会话已经在运行", className: "ScannerViewModel")
return
}
// 检查会话配置是否完整
if captureSession.inputs.isEmpty || captureSession.outputs.isEmpty {
logWarning("⚠️ 捕获会话配置不完整,重新设置", className: "ScannerViewModel")
setupCaptureSession()
return
}
logInfo("🚀 启动扫描会话", className: "ScannerViewModel")
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
guard let self = self else { return }
self.captureSession?.startRunning()
// 检查启动状态
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
if self.captureSession?.isRunning == true {
logInfo("✅ 扫描会话启动成功", className: "ScannerViewModel")
} else {
logWarning("⚠️ 扫描会话启动失败", className: "ScannerViewModel")
logWarning("⚠️ 扫描会话启动失败,尝试重试", className: "ScannerViewModel")
// 启动失败时重试一次
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.retryStartScanning()
}
}
}
}
}
private func retryStartScanning() {
logInfo("🔄 重试启动扫描", className: "ScannerViewModel")
guard captureSession != nil else {
logError("❌ 捕获会话为空,无法重试", className: "ScannerViewModel")
return
}
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
self?.captureSession?.startRunning()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
if self?.captureSession?.isRunning == true {
logInfo("✅ 重试启动扫描成功", className: "ScannerViewModel")
} else {
logError("❌ 重试启动扫描失败", className: "ScannerViewModel")
}
}
}

Loading…
Cancel
Save