如何在Swift的Moya中添加进度视图?以下代码的ProgressBlock使用是否正确?
在Swift的Moya框架中添加进度视图及代码问题解析
一、如何在Moya中添加进度视图
Moya的request方法自带progress闭包,它会持续返回Progress对象,帮你实时追踪请求的上传/下载进度。你可以借助这个闭包来绑定进度视图(比如系统的UIProgressView或自定义HUD),具体步骤如下:
- 准备进度视图:先在界面中添加进度组件,以系统
UIProgressView为例:
let progressView = UIProgressView(progressViewStyle: .default) progressView.frame = CGRect(x: 20, y: 100, width: view.frame.width - 40, height: 2) progressView.tintColor = .systemBlue view.addSubview(progressView)
- 在请求中绑定进度逻辑:调用
request时传入progress闭包,通过Progress对象的completedUnitCount和totalUnitCount计算进度百分比,注意必须在主线程更新UI:
let provider = MoyaProvider<ServiceType>() // 请求开始时显示进度相关视图 progressView.isHidden = false self.view.showLoadingHUD() provider.request(.GetRouteDetail, callbackQueue: DispatchQueue.main) { result in // 请求结束后统一隐藏进度视图 progressView.isHidden = true self.view.hideLoadingHUD() switch result { case .success(let response): print("请求成功:\(response)") // 后续业务逻辑处理 case .failure(let error): print("请求失败:\(error.localizedDescription)") // 错误提示逻辑 } } progress: { progress in DispatchQueue.main.async { // 计算0~1范围的进度值 let progressValue = Float(progress.completedUnitCount) / Float(progress.totalUnitCount) self.progressView.progress = progressValue // 可选:进度完成时的额外处理 if progress.isCompleted { print("请求进度已完成") } } }
二、你的ProgressBlock使用方式的问题分析
看你给出的代码片段,这里存在几个明显的逻辑问题:
- 参数类型混淆:
progress闭包的参数是Progress类型,不是response,你写的response.completed应该是progress.isCompleted(注意属性名是isCompleted,不是completed)。 - HUD显示逻辑冗余:你在每次进度回调时都调用
showLoadingHUD(),这完全没必要——HUD只需要在请求开始时显示一次即可,反复调用会造成不必要的UI刷新。 - 请求成功时未隐藏HUD:在
result闭包的.success分支里,你没有调用hideLoadingHUD(),这会导致请求成功后HUD一直停留在界面上。 - 线程安全风险:虽然你设置了
callbackQueue: DispatchQueue.main,但最好还是在进度闭包中明确用DispatchQueue.main.async包裹UI更新代码,避免潜在的线程问题。
修正后的代码示例
let instance = MoyaProvider<ServiceType>() // 请求开始时仅显示一次HUD self.view.showLoadingHUD() instance.request(.GetRouteDetail, callbackQueue: DispatchQueue.main) { result in // 请求结束,无论成功失败都隐藏HUD self.view.hideLoadingHUD() switch result { case .success(let response): print("请求成功:\(response)") case .failure(let error): print("请求失败:\(error)") } } progress: { progress in DispatchQueue.main.async { // 可选:如果需要展示具体进度值,在这里处理 let progressValue = Float(progress.completedUnitCount) / Float(progress.totalUnitCount) print("当前请求进度:\(progressValue * 100)%") // 不需要在这里处理HUD显示/隐藏,请求结束统一处理即可 if progress.isCompleted { print("进度追踪完成") } } }
内容的提问来源于stack exchange,提问作者Vasanthan Prem
相关产品推荐
相关产品推荐

