如何在完全不发送请求的情况下拦截Moya请求和return失败响应

How to intercept Moya request and return failure response without sending the request at all

我正在使用 Moya 库来处理网络层,并且我已经有一个自定义插件可以将身份验证令牌添加到 header。

我想做的是让这个插件取消请求,如果令牌还不可用,return 一个失败响应(或抛出一个错误)。

P.S。我扩展了协议 TargetType 以添加额外的变量来指示目标是否需要身份验证,因此我需要访问这些数据以确定 header 中是否需要身份验证令牌。

这是我的自定义插件的快照:

struct AuthTokenPlugin: PluginType {
    let tokenClosure:()->String?

    func prepare(_ request: URLRequest, target: TargetType) -> URLRequest {
        guard let target = target as? AuthorizebleTargetType, target.needsAuth else {
            return request
        }

        guard let token = tokenClosure() else {
            // Here where a failure response will be triggered or an error should be thrown  
            return ......
        }

        var request = request
        request.addValue( "Token " + token, forHTTPHeaderField:"Authorization")
        return request
    }
}

P.S.2:抛出错误不是一个好的做法,而且这是不可能的,因为封闭函数 "prepare(_:target:)" 没有声明 'throws'.

我不认为我们可以使用 protocol TargetType 来实现这样的逻辑,因为他的方法不是 return 布尔值,也不是 throw-marked。

看看 MoyaProvider 初始化参数。其中有一个 requestClosure 参数。您可以 copy-paste 并将此参数的默认实现替换为您自己的实现,这将检查 header 对 Endpoint 的授权。

此闭包的默认实现:

final class func defaultRequestMapping(for endpoint: Endpoint, closure: RequestResultClosure) {
        do {
            let urlRequest = try endpoint.urlRequest()
            closure(.success(urlRequest))
        } catch MoyaError.requestMapping(let url) {
            closure(.failure(MoyaError.requestMapping(url)))
        } catch MoyaError.parameterEncoding(let error) {
            closure(.failure(MoyaError.parameterEncoding(error)))
        } catch {
            closure(.failure(MoyaError.underlying(error, nil)))
        }
    }

UPD 加上我的评论:

我建议检查 Endpoint 是否有 header 键“Authorization”,但它的值是空字符串,然后用 .failure 大小写调用 closure 参数在 requestClosure