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

如何在Swift的Moya中添加进度视图?以下代码的ProgressBlock使用是否正确?

在Swift的Moya框架中添加进度视图及代码问题解析

一、如何在Moya中添加进度视图

Moya的request方法自带progress闭包,它会持续返回Progress对象,帮你实时追踪请求的上传/下载进度。你可以借助这个闭包来绑定进度视图(比如系统的UIProgressView或自定义HUD),具体步骤如下:

  1. 准备进度视图:先在界面中添加进度组件,以系统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)
  1. 在请求中绑定进度逻辑:调用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使用方式的问题分析

看你给出的代码片段,这里存在几个明显的逻辑问题:

  1. 参数类型混淆:progress闭包的参数是Progress类型,不是response,你写的response.completed应该是progress.isCompleted(注意属性名是isCompleted,不是completed)。
  2. HUD显示逻辑冗余:你在每次进度回调时都调用showLoadingHUD(),这完全没必要——HUD只需要在请求开始时显示一次即可,反复调用会造成不必要的UI刷新。
  3. 请求成功时未隐藏HUD:在result闭包的.success分支里,你没有调用hideLoadingHUD(),这会导致请求成功后HUD一直停留在界面上。
  4. 线程安全风险:虽然你设置了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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:48:15