【问题标题】:How to intercept Moya request and return failure response without sending the request at all如何在不发送请求的情况下拦截 Moya 请求并返回失败响应
【发布时间】:2019-10-22 11:13:09
【问题描述】:

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

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

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

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

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:)”未声明为“抛出”。

【问题讨论】:

  • 为什么抛出错误不是一个好习惯?您可能更喜欢返回Optional URLRequest。
  • 不是一个好习惯,因为它在逻辑上是响应的正常失败,而不是常规逻辑的异常(如 JSON 解析错误)。 Optional URLRequest 可能会解决这个问题,但它也是不可能的,因为它没有在 PluginType 协议中声明为可选

标签: ios swift moya


【解决方案1】:

我不认为我们可以使用protocol TargetType 来实现这样的逻辑,因为他的方法不返回 Bool 值并且没有抛出标记。

看看MoyaProvider init 参数。其中有一个requestClosure 参数。您可以复制粘贴并将此参数的默认实现替换为您自己的实现,这将检查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是否有带有“授权”键的标题,但它的值是空字符串,然后在requestClosure.failure的情况下调用closure参数

【讨论】:

  • 感谢您的回复。但我的问题并不完整。据我了解,这个requestClosure 有Endpoint 对象而不是TargetType。但我需要TargetType 对象来确定标头中是否需要身份验证令牌。我用详细信息更新了我的问题。
  • 您可以检查Endpont是否有带有“Authorization”键的标题,但它的值是空字符串,然后在requestClosure.failure的情况下调用closure参数
  • 再次感谢。您能否编辑您的答案以包含此建议,以便其他人无需阅读 cmets 即可获得完整答案
猜你喜欢
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多