Files
e-party-iOS/issues/图片上传崩溃修复.md
edwinQQQ b966e24532 feat: 更新COSManager和相关视图以增强图片上传功能
- 修改COSManagerAdapter以支持新的TCCos组件,确保与腾讯云COS的兼容性。
- 在CreateFeedFeature中新增图片上传相关状态和Action,优化图片选择与上传逻辑。
- 更新CreateFeedView以整合图片上传功能,提升用户体验。
- 在多个视图中添加键盘状态管理,改善用户交互体验。
- 新增COS相关的测试文件,确保功能的正确性和稳定性。
2025-07-31 11:41:56 +08:00

3.8 KiB
Raw Blame History

图片上传崩溃问题修复

问题描述

用户在上传图片时遇到应用崩溃,崩溃调用栈显示:

Thread 14 Queue: com.apple.root.user-initiated-qos (concurrent)
0 _dispatch_assert_queue_fail
5 _34-[QCloudFakeRequestOperation main]_block_invoke
6 _41-[QCloudAbstractRequest _notifySuccess:]_block_invoke

根本原因分析

  1. 队列断言失败_dispatch_assert_queue_fail 表明在错误的队列上执行了操作
  2. 腾讯云 COS 回调队列问题COS 的回调可能在后台队列执行,但代码尝试在主队列更新 UI
  3. 并发安全问题withCheckedContinuation 的回调可能在任意队列执行,导致队列断言失败
  4. 调试信息队列问题debugInfoSync 函数使用 Task 异步执行,可能导致队列冲突

修复方案

1. 强制回调在主队列执行

COSManager.swift 中修改 uploadImage 方法:

request.setFinish { result, error in
    // 强制切换到主队列执行回调,避免队列断言失败
    DispatchQueue.main.async {
        if let error = error {
            print("❌ 图片上传失败: \(error.localizedDescription)")
            continuation.resume(returning: nil)
        } else {
            // 构建云地址
            let cloudURL = "\(prefix)\(domain)/\(key)"
            print("✅ 图片上传成功: \(cloudURL)")
            continuation.resume(returning: cloudURL)
        }
    }
}

2. 进度回调队列安全

request.sendProcessBlock = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) in
    // 强制切换到主队列执行进度回调,避免队列断言失败
    DispatchQueue.main.async {
        print("📊 上传进度: \(bytesSent), \(totalBytesSent), \(totalBytesExpectedToSend)")
    }
}

3. 添加超时和错误处理

// 使用 TaskGroup 添加超时处理
return await withTaskGroup(of: String?.self) { group in
    group.addTask {
        await withCheckedContinuation { continuation in
            // 设置超时处理
            let timeoutTask = Task {
                try? await Task.sleep(nanoseconds: 60_000_000_000) // 60秒超时
                continuation.resume(returning: nil)
            }
            
            request.setFinish { result, error in
                timeoutTask.cancel()
                // ... 回调处理
            }
        }
    }
}

4. COS 初始化队列安全

private func ensureCOSInitialized(tokenData: TcTokenData) {
    guard !Self.isCOSInitialized else { return }
    
    // 确保在主队列执行 COS 初始化
    if Thread.isMainThread {
        performCOSInitialization(tokenData: tokenData)
    } else {
        DispatchQueue.main.sync {
            performCOSInitialization(tokenData: tokenData)
        }
    }
}

5. 替换调试信息调用

将所有 debugInfoSync 调用替换为 print,避免异步调试信息导致的队列问题。

修复效果

  1. 消除队列断言失败:所有回调都在主队列执行
  2. 提高稳定性:添加超时处理和错误恢复机制
  3. 改善调试体验:使用同步打印避免队列冲突
  4. 保持功能完整:所有原有功能保持不变

测试建议

  1. 测试单张图片上传
  2. 测试多张图片批量上传
  3. 测试网络异常情况下的上传
  4. 测试大文件上传
  5. 测试并发上传场景

相关文件

  • yana/Utils/COSManager.swift - 主要修复文件
  • yana/Features/EditFeedFeature.swift - 已正确使用 MainActor
  • yana/Features/CreateFeedFeature.swift - 已正确使用 MainActor
  • yana/Features/AppSettingFeature.swift - 已正确使用 MainActor

注意事项

  1. 所有 UI 更新操作必须在主队列执行
  2. 腾讯云 COS 回调必须在主队列处理
  3. 避免在回调中使用异步调试信息
  4. 添加适当的超时和错误处理机制