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

Swift中如何监听API请求状态从proceeding变为completed?

解决方案:监听API状态从-proceeding-变为-completed-

方案1:带延迟的轮询(推荐)

核心思路是当请求返回-proceeding-状态时,等待指定时间后重复发起请求,直到状态变为-completed-或达到重试上限,避免无限请求。

修改后的代码如下:

func fetchURL(url: String, retryCount: Int = 5, delay: TimeInterval = 3) {
    // 重试次数耗尽时终止请求
    guard retryCount > 0 else {
        print("DEBUG: - 重试次数耗尽,请求终止")
        return
    }
    
    let apiUrl = URL(string: url)!
    let session = URLSession.shared
    
    let task = session.dataTask(with: apiUrl) { [weak self] (data, response, error) in
        if let error = error {
            print("DEBUG: - Error: \(error)")
            return
        }
        guard let data = data else {
            print("DEBUG: - No data received")
            return
        }

        do {
            let decoder = JSONDecoder()
            let dustResponse = try decoder.decode(FetchData.self, from: data)
            
            print("DEBUG: - Status: \(dustResponse.detail.status)")
            print("DEBUG: - Message: \(dustResponse.detail.message)")
            
            switch dustResponse.detail.status {
            case "-completed-":
                // 状态完成,执行你的业务操作
                self?.handleCompleted(response: dustResponse)
            case "-proceeding-":
                // 状态未完成,延迟后重试
                print("DEBUG: - 处理中,\(delay)秒后重试...")
                DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
                    self?.fetchURL(url: url, retryCount: retryCount - 1, delay: delay)
                }
            default:
                print("DEBUG: - 未知状态: \(dustResponse.detail.status)")
            }
        } catch {
            print("DEBUG: - Error decoding JSON: \(error)")
        }
    }
    task.resume()
}

// 状态完成后的业务处理方法
func handleCompleted(response: FetchData) {
    // 在这里写你需要的逻辑,比如更新UI、解析完整数据等
    print("DEBUG: - 状态已完成,开始处理业务逻辑")
}

代码说明:

  • retryCount:限制最大重试次数,防止无限请求
  • delay:控制重试间隔,根据API实际渲染耗时调整
  • [weak self]:避免循环引用导致内存泄漏
  • 分支处理:完成状态触发业务逻辑,未完成则延迟重试

方案2:支持取消的轮询(可选)

如果需要随时终止轮询流程,可以保存当前请求任务,提供取消入口:

private var currentPollTask: URLSessionTask?

func fetchURL(url: String, retryCount: Int = 5, delay: TimeInterval = 3) {
    guard retryCount > 0 else {
        print("DEBUG: - 重试次数耗尽")
        currentPollTask = nil
        return
    }
    
    // 取消之前的未完成任务
    currentPollTask?.cancel()
    
    let apiUrl = URL(string: url)!
    let session = URLSession.shared
    
    let task = session.dataTask(with: apiUrl) { [weak self] (data, response, error) in
        guard let self = self else { return }
        
        if let error = error {
            if (error as NSError).code == NSURLErrorCancelled {
                print("DEBUG: - 请求已取消")
            } else {
                print("DEBUG: - Error: \(error)")
            }
            self.currentPollTask = nil
            return
        }
        guard let data = data else {
            print("DEBUG: - No data received")
            self.currentPollTask = nil
            return
        }

        do {
            let decoder = JSONDecoder()
            let dustResponse = try decoder.decode(FetchData.self, from: data)
            
            switch dustResponse.detail.status {
            case "-completed-":
                self.handleCompleted(response: dustResponse)
                self.currentPollTask = nil
            case "-proceeding-":
                print("DEBUG: - 处理中,\(delay)秒后重试...")
                DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
                    self.fetchURL(url: url, retryCount: retryCount - 1, delay: delay)
                }
            default:
                print("DEBUG: - 未知状态")
                self.currentPollTask = nil
            }
        } catch {
            print("DEBUG: - Error decoding JSON: \(error)")
            self.currentPollTask = nil
        }
    }
    currentPollTask = task
    task.resume()
}

// 外部调用此方法可终止轮询
func cancelPolling() {
    currentPollTask?.cancel()
}

注意事项:

  • 不要设置过短的重试间隔,避免给API服务器造成压力
  • 根据实际业务场景调整重试次数,比如渲染耗时较长可适当增加
  • 如果API支持Webhook或WebSocket推送状态变更,优先使用这类方式替代轮询(若API提供该能力)

内容的提问来源于stack exchange,提问作者SwiftTry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:43:12