快速异步网络。出现错误时如何重试?

标签 swift firebase api networking async-await

我已经使用异步创建了一个通用网络功能,该功能工作正常,但我希望能够在抛出错误(例如 token 过期)时重试该请求。我该如何做到这一点而不需要更改我所有的 DO Catch?

func request<T: Codable>(_ endpoint: Endpoint) async throws -> T {
    
    guard let url = endpoint.url else {
        throw NetworkError.badURL
    }
    
    guard let token = idToken else {
        throw NetworkError.invalidToken
    }
    
    let request = buildRequest(from: url, methodType: endpoint.methodType, idToken: token)
    
    let (data, response) = try await URLSession.shared.data(for: request)
    guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
        
        //RETRY X AMOUNT OF TIMES <<<
        
        throw NetworkError.invalidResponse
    }
    
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    guard let result = try? decoder.decode(T.self, from: data) else {
        throw NetworkError.decodingError
    }
    
    print("Result: \(result)")
    
    return result
}

最佳答案

如果您想这样做,我建议编写一个包装重试逻辑的 data(for:delegate:) 的再现,例如:

extension URLSession {
    func data(for request: URLRequest, delegate: URLSessionTaskDelegate? = nil, maxRetries: Int) async throws -> (Data, URLResponse) {
        for _ in 0 ..< maxRetries {
            let (data, response) = try await data(for: request, delegate: delegate)
            guard let response = response as? HTTPURLResponse else {
                throw URLError(.badServerResponse)
            }
            if 200..<300 ~= response.statusCode {     // as an aside, note, any 2xx response is success
                return (data, response)
            }
        }

        throw NetworkError.invalidResponse
    }
}

然后,您可以替换:

let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
    
    //RETRY X AMOUNT OF TIMES <<<
    
    throw NetworkError.invalidResponse
}

与:

let (data, response) = try await URLSession.shared.data(for: request, maxRetries: 3)

关于快速异步网络。出现错误时如何重试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75081648/

相关文章:

ios - 我的函数需要用户位置,但它返回 nil

javascript - 使用自定义行为覆盖 Web Firebase 云消息传递后台通知

firebase - 更新 map 字段-Flutter

java - 如何在 Firestore 中获取特定集合?

python - 类型错误:必须使用 'method name' 实例作为第一个参数调用未绑定(bind)方法 'class name'(改为使用 str 实例)

javascript - react 。如何仅对现有 key 使用 fetch 和 setState 来处理 API 响应中丢失的 key ?

javascript - json 图像 Angular 框架

ios - UITableViewCell 最初没有正确格式化

ios - Swift 解码字符串 JSON 失败

swift - 如何评估同质集合的平等性?