当我得到 statusCode 401 时重试 alamofire 请求

问题描述 投票:0回答:0

我有带有 alamofire 的请求生成器,有时我有 401 statusCode(关于需要刷新的令牌)。 我需要如何更改类网络才能刷新令牌并重新发送请求?

当我在响应中收到 statusCode 401 - 我尝试调用 refreshToken 请求,但我无法将我的 loginService 添加到此类,而且我也无法理解如何在此管理器中重复请求。

如果可以,请在答案中写一个例子。

下面是我的网络课:

class Network {

    typealias Method = Alamofire.HTTPMethod
    typealias Headers = HTTPHeaders
    typealias ResponseResult = Result<Response, Error>
    typealias Completion = (ResponseResult) -> Void

    // MARK: - Properties

    lazy var baseURL: URL = {
        #if PROD
        return URL(string: "https://xxxxx.xxxx.com/")!
        #else
        return URL(string: "https://xxxxx.xxxx.com/")!
        #endif
    }()
    
    func request(_ target: RequestConvertible,
                 queue: DispatchQueue,
                 completion: @escaping Completion) {
        do {
            let request = try makeURLRequest(for: target)
            performRequest(AF.request(request), queue: queue, target: target, completion: completion)
        } catch {
            completion(.failure(error))
        }
    }

    func requestWithDecode<T: Decodable>(_ target: RequestConvertible,
                                         value: T.Type,
                                         queue: DispatchQueue,
                                         completion: @escaping (Result<T, Error>) -> Void) {
        request(target, queue: queue) { [weak self] result in
            switch result {
            case .success(let response):
                if response.statusCode == 401 {
                    debugPrint("401 status code")
                }
               
                do {
                    completion(try self?.handleResponse(response: response, value: value)
                                ?? .failure(CommonError.undefined))
                } catch {
                        completion(.failure(error))
                }
            case .failure(let error):
                completion(.failure(error))
            }
        }
    }

    // MARK: - Private

    private func handleResponse<T: Decodable>(response: Response, value: T.Type) throws -> Result<T, Error> {
        let apiResponse = try response.decode(APIResponse<T>.self)
        if let result = apiResponse.data {
            return .success(result)
        } else if let error = apiResponse.errors {
            return .failure(error)
        } else {
            return .failure(CommonError.custom(apiResponse.errors?.message.joined(separator: " ") ?? ""))
        }
    }

    private func makeURLRequest(for target: RequestConvertible) throws -> URLRequest {
        let url = target.baseURL ?? baseURL
        let pathURL = target.path.isEmpty ? url : url.appendingPathComponent(target.path)
        var request = try URLRequest(url: pathURL).encoded(for: target)
        request.httpMethod = target.method.rawValue
        target.headers?.dictionary.forEach { request.setValue($1, forHTTPHeaderField: $0) }
        return request
    }

    private func performRequest(_ request: DataRequest,
                                queue: DispatchQueue,
                                target: RequestConvertible,
                                completion: @escaping Completion) {
        request.responseData(queue: queue) { responseData in
            guard let response = responseData.response else {
                return completion(.failure(responseData.error ?? CommonError.undefined))
            }
            completion(Result { Response(data: responseData.data ?? Data(), response: response) })
        }
        request.resume()
    }
}
swift alamofire http-status-code-401 refresh-token alamofire-request
© www.soinside.com 2019 - 2024. All rights reserved.