如何观察 Swift 中 API 请求状态的变化?

How to observe change of API request status in Swift?

提问人:SwiftTry 提问时间:10/21/2023 最后编辑:Brian Tompsett - 汤莱恩SwiftTry 更新时间:10/21/2023 访问量:35

问:

我正在处理一个项目,我正在向项目中的 API URL 发送 GET 请求。(如下)

实际上,这里的一切都对我有用。但问题是;当我第一次发送请求时,“Status”值显示为 -proceeding-。过了一会儿,它变成了 -completed-。(因为我正在等待 API 中的渲染)

我的问题是;如何知道此状态值何时从“正在进行”更改为“已完成”?因为我想在完成后执行不同的操作。有什么想法吗?

    func fetchURL(url: String) {
    
    let apiUrl = URL(string: url)!

    let session = URLSession.shared

    let task = session.dataTask(with: apiUrl) { (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)")
        } catch {
            print("DEBUG: - Error decoding JSON: \(error)")
        }
    }
    task.resume()
    
}
Swift 回调 请求 观察者

评论


答:

0赞 Domique 623 10/21/2023 #1

由于该过程是由 API 的服务器完成的,因此您无法真正知道它何时完成。我建议看看您是否有办法在处理完成时通知某种 Web 套接字。如果没有,可以每 x 秒请求一次状态,以查看处理是否完成:

@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
func APIFetchResult(apiUrl: URL) async -> FetchData? {
    return await withCheckedContinuation({ (result: CheckedContinuation<Continuation?, Never>) in
       let session = URLSession.shared

       let task = session.dataTask(with: apiUrl) { (data, response, error) in
           if let error = error {
              print("DEBUG: - Error: \(error)")
              result.resume(returning: nil)
           }
           guard let data = data else {
              print("DEBUG: - No data received")
              result.resume(returning: nil)
           }

           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)")
              result.resume(returning: dustResponse)
           } catch {
              print("DEBUG: - Error decoding JSON: \(error)")
              result.resume(returning: nil)
           }
       }
       task.resume() 
    })
}


let finalResult: FinalResultType? = nil

while finalResult == nil {
    finalResult = await APIFetchResult(apiUrl: apiUrl)
    await Task.sleep(5_000_000_000) // wait 5 seconds before re-doing the request
}

// do whatever you want after

在这段代码中,我们:

  1. 使用 Swift 标准库的本机函数创建函数的 await/async 版本。fetchURLwithCheckedContinuation
  2. 每 5 秒 + 执行时间调用一次,并执行此操作,直到定义为止。finalResult

希望这对你有所帮助!