|
|
# 相机授权功能实现说明
|
|
|
|
|
|
## 🎯 功能概述
|
|
|
|
|
|
为 MyQrCode 应用添加了完整的相机权限管理功能,包括权限检查、权限请求、权限状态显示和用户引导。
|
|
|
|
|
|
## 🔧 技术实现
|
|
|
|
|
|
### 1. **权限状态管理**
|
|
|
|
|
|
在 `ScannerViewModel` 中添加了权限相关的状态:
|
|
|
|
|
|
```swift
|
|
|
@Published var cameraAuthorizationStatus: AVAuthorizationStatus = .notDetermined
|
|
|
@Published var showPermissionAlert = false
|
|
|
```
|
|
|
|
|
|
### 2. **权限检查流程**
|
|
|
|
|
|
#### **初始化时权限检查**
|
|
|
```swift
|
|
|
override init() {
|
|
|
super.init()
|
|
|
checkCameraPermission() // 替换原来的 setupCaptureSession()
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### **权限状态检查方法**
|
|
|
```swift
|
|
|
private func checkCameraPermission() {
|
|
|
switch AVCaptureDevice.authorizationStatus(for: .video) {
|
|
|
case .authorized:
|
|
|
// 已授权,设置相机会话
|
|
|
setupCaptureSession()
|
|
|
|
|
|
case .notDetermined:
|
|
|
// 未确定,请求权限
|
|
|
requestCameraPermission()
|
|
|
|
|
|
case .denied, .restricted:
|
|
|
// 被拒绝或受限,显示权限提示
|
|
|
showPermissionAlert = true
|
|
|
|
|
|
@unknown default:
|
|
|
// 未知状态
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 3. **权限请求处理**
|
|
|
|
|
|
#### **自动权限请求**
|
|
|
```swift
|
|
|
private func requestCameraPermission() {
|
|
|
AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in
|
|
|
DispatchQueue.main.async {
|
|
|
if granted {
|
|
|
self?.cameraAuthorizationStatus = .authorized
|
|
|
self?.setupCaptureSession()
|
|
|
} else {
|
|
|
self?.cameraAuthorizationStatus = .denied
|
|
|
self?.showPermissionAlert = true
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### **手动权限刷新**
|
|
|
```swift
|
|
|
func refreshCameraPermission() {
|
|
|
checkCameraPermission()
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 4. **设置页面跳转**
|
|
|
|
|
|
```swift
|
|
|
func openSettings() {
|
|
|
if let settingsUrl = URL(string: UIApplication.openSettingsURLString) {
|
|
|
UIApplication.shared.open(settingsUrl) { success in
|
|
|
// 处理跳转结果
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 📱 用户界面
|
|
|
|
|
|
### 1. **权限状态视图**
|
|
|
|
|
|
创建了 `CameraPermissionView` 来显示不同权限状态下的UI:
|
|
|
|
|
|
#### **未确定状态**
|
|
|
- 显示相机图标和说明文字
|
|
|
- 提供"授予相机权限"按钮
|
|
|
- 点击后自动请求权限
|
|
|
|
|
|
#### **被拒绝状态**
|
|
|
- 显示权限被拒绝的说明
|
|
|
- 提供"打开设置"按钮
|
|
|
- 引导用户到系统设置中手动开启
|
|
|
|
|
|
#### **受限状态**
|
|
|
- 显示权限受限的说明
|
|
|
- 提供相应的解决方案
|
|
|
|
|
|
### 2. **UI 组件结构**
|
|
|
|
|
|
```swift
|
|
|
struct CameraPermissionView: View {
|
|
|
let authorizationStatus: AVAuthorizationStatus
|
|
|
let onRequestPermission: () -> Void
|
|
|
let onOpenSettings: () -> Void
|
|
|
|
|
|
var body: some View {
|
|
|
VStack(spacing: 30) {
|
|
|
// 相机图标
|
|
|
Image(systemName: "camera.fill")
|
|
|
|
|
|
// 标题和描述
|
|
|
Text("camera_permission_title".localized)
|
|
|
Text(getDescriptionText())
|
|
|
|
|
|
// 操作按钮
|
|
|
VStack(spacing: 15) {
|
|
|
if authorizationStatus == .notDetermined {
|
|
|
// 请求权限按钮
|
|
|
} else if authorizationStatus == .denied || authorizationStatus == .restricted {
|
|
|
// 打开设置按钮
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 3. **权限状态集成**
|
|
|
|
|
|
在 `ScannerView` 中根据权限状态显示不同的UI:
|
|
|
|
|
|
```swift
|
|
|
var body: some View {
|
|
|
ZStack {
|
|
|
if scannerViewModel.cameraAuthorizationStatus == .authorized {
|
|
|
// 相机预览和扫描UI
|
|
|
CameraPreviewView(...)
|
|
|
ScanningOverlayView(...)
|
|
|
// ... 其他扫描相关组件
|
|
|
} else {
|
|
|
// 权限相关UI
|
|
|
CameraPermissionView(...)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 🌐 多语言支持
|
|
|
|
|
|
### 1. **英文本地化**
|
|
|
|
|
|
```strings
|
|
|
"camera_permission_title" = "Camera Permission Required";
|
|
|
"camera_permission_description" = "This app needs access to your camera to scan QR codes and barcodes. Please grant camera permission to continue.";
|
|
|
"camera_permission_denied" = "Camera access has been denied. Please enable camera permission in Settings to use the scanner.";
|
|
|
"request_camera_permission" = "Grant Camera Access";
|
|
|
"open_settings" = "Open Settings";
|
|
|
```
|
|
|
|
|
|
### 2. **中文本地化**
|
|
|
|
|
|
```strings
|
|
|
"camera_permission_title" = "需要相机权限";
|
|
|
"camera_permission_description" = "此应用需要访问您的相机来扫描二维码和条形码。请授予相机权限以继续使用。";
|
|
|
"camera_permission_denied" = "相机访问被拒绝。请在设置中启用相机权限以使用扫描器。";
|
|
|
"request_camera_permission" = "授予相机权限";
|
|
|
"open_settings" = "打开设置";
|
|
|
```
|
|
|
|
|
|
## 🔄 权限状态监听
|
|
|
|
|
|
### 1. **自动状态更新**
|
|
|
|
|
|
```swift
|
|
|
.onReceive(scannerViewModel.$cameraAuthorizationStatus) { status in
|
|
|
if status == .authorized {
|
|
|
logInfo("🎯 相机权限已授权,启动扫描", className: "ScannerView")
|
|
|
scannerViewModel.startScanning()
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 2. **扫描控制**
|
|
|
|
|
|
```swift
|
|
|
.onAppear {
|
|
|
// 只有在相机权限已授权时才启动扫描
|
|
|
if scannerViewModel.cameraAuthorizationStatus == .authorized {
|
|
|
scannerViewModel.startScanning()
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 📋 权限状态类型
|
|
|
|
|
|
### 1. **AVAuthorizationStatus 枚举**
|
|
|
|
|
|
- **`.notDetermined`**: 用户尚未做出选择
|
|
|
- **`.authorized`**: 用户已授权访问相机
|
|
|
- **`.denied`**: 用户拒绝访问相机
|
|
|
- **`.restricted`**: 相机访问受限(如家长控制)
|
|
|
|
|
|
### 2. **状态转换流程**
|
|
|
|
|
|
```
|
|
|
notDetermined → 请求权限 → authorized/denied
|
|
|
denied → 用户手动开启 → authorized
|
|
|
restricted → 需要管理员操作 → authorized
|
|
|
```
|
|
|
|
|
|
## 🧪 测试场景
|
|
|
|
|
|
### 1. **首次安装**
|
|
|
- 应用启动时自动请求权限
|
|
|
- 用户可以选择允许或拒绝
|
|
|
|
|
|
### 2. **权限被拒绝**
|
|
|
- 显示权限被拒绝的说明
|
|
|
- 提供打开设置的按钮
|
|
|
- 用户可以从设置中重新开启
|
|
|
|
|
|
### 3. **权限恢复**
|
|
|
- 用户从设置返回后自动检测权限状态
|
|
|
- 权限恢复后自动启动扫描功能
|
|
|
|
|
|
### 4. **权限受限**
|
|
|
- 显示相应的说明和解决方案
|
|
|
- 引导用户联系管理员或检查设备设置
|
|
|
|
|
|
## 🔒 隐私和安全
|
|
|
|
|
|
### 1. **最小权限原则**
|
|
|
- 只请求必要的相机权限
|
|
|
- 不收集或存储相机数据
|
|
|
- 权限仅用于扫描功能
|
|
|
|
|
|
### 2. **用户控制**
|
|
|
- 用户可以随时在设置中关闭权限
|
|
|
- 应用会优雅地处理权限变化
|
|
|
- 提供清晰的权限说明
|
|
|
|
|
|
### 3. **错误处理**
|
|
|
- 权限被拒绝时提供友好的错误信息
|
|
|
- 引导用户解决问题的方法
|
|
|
- 不会因为权限问题导致应用崩溃
|
|
|
|
|
|
## 🚀 部署说明
|
|
|
|
|
|
### 1. **Info.plist 配置**
|
|
|
确保在 `Info.plist` 中添加相机权限描述:
|
|
|
|
|
|
```xml
|
|
|
<key>NSCameraUsageDescription</key>
|
|
|
<string>此应用需要访问相机来扫描二维码和条形码</string>
|
|
|
```
|
|
|
|
|
|
### 2. **权限测试**
|
|
|
- 在真机上测试权限流程
|
|
|
- 验证不同权限状态下的UI显示
|
|
|
- 测试权限恢复后的功能
|
|
|
|
|
|
### 3. **用户体验**
|
|
|
- 权限请求时机合理
|
|
|
- 错误信息清晰易懂
|
|
|
- 操作流程简单直观
|
|
|
|
|
|
## 📊 功能特性总结
|
|
|
|
|
|
- ✅ **自动权限检查**: 应用启动时自动检查相机权限
|
|
|
- ✅ **智能权限请求**: 只在必要时请求权限
|
|
|
- ✅ **友好错误提示**: 权限被拒绝时提供清晰的说明
|
|
|
- ✅ **设置页面跳转**: 一键跳转到系统设置
|
|
|
- ✅ **状态自动更新**: 权限状态变化时自动更新UI
|
|
|
- ✅ **多语言支持**: 支持中英文界面
|
|
|
- ✅ **优雅降级**: 无权限时显示相应的提示界面
|
|
|
- ✅ **权限恢复**: 权限恢复后自动启动扫描功能
|
|
|
|
|
|
通过这些功能,用户可以获得完整的相机权限管理体验,确保应用能够正常使用相机功能,同时尊重用户的隐私选择。 |