我有带有 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()
}
}