繁体   English   中英

Swift 异步网络。 我如何重试错误?

[英]Swift Async Networking. How do I RETRY on error?

我已经使用 async 创建了一个 generic.networking function,它工作正常,但我希望能够在它抛出错误时重试请求,例如,如果令牌已过期。 我将如何做到这一点而不必更改我所有的 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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM