使用 Moya 获取响应标头

Posted

技术标签:

【中文标题】使用 Moya 获取响应标头【英文标题】:Get response header with Moya 【发布时间】:2017-05-03 06:12:00 【问题描述】:

我在我的 swift 应用程序中使用 Moya 来处理网络请求。

我能够使用 Moya-Object Mapper 获取请求并映射结果。

我之前用过alamofire,熟悉如何发帖、获取请求和读取响应头。

但是,我似乎无法理解如何在 Moya 中做同样的事情。

我确实浏览了文档,但它没有说明有关读取响应标头的任何内容。

是否有任何示例或教程可以让我了解如何进行 HTTP 身份验证并读取响应标头。以及如何发出 post 请求并将参数作为字段参数或 json 正文发送。

我已经完成了 Moya 的例子。

任何帮助将不胜感激。谢谢。

【问题讨论】:

【参考方案1】:

Moya 中的响应标头目前实际上相当困难。这是 Moya 代码中不受欢迎的旧式沮丧。我永远不知道他们为什么不喜欢它。

我开了一个相关的issue指出来:Moya header

并通过拉取请求进行一些更改:Moya header PR

这是我的个人代码示例,我在其中强制转换响应以访问标头:

class GetTokenRequest 

    private let requestService = AuthorizedRequest()

    func request() -> Observable<AuthorizedResult<GetTokenEntityResult>> 
        return Observable.deferred  [weak self] in
            guard let wself = self else 
                return Observable.empty()
            

            let req = wself.requestService.makeRawRequest  userId in
                    let obj = GetTokenEntity(lang: currentLanguage(), userId: userId)
                    return MtxAPI.getToken(obj)
                
                .shareReplay(1)

            return req.map  result in
                switch result 
                case .success(let response):
                    let urlResponse = response.response as! HTTPURLResponse
                    guard let token = urlResponse.allHeaderFields["Token"] as? String else 
                        return AuthorizedResult.fail(RequestError.technical)
                    
                    return AuthorizedResult.success(GetTokenEntityResult(token: token))

                case .fail(let error): return AuthorizedResult.fail(error)
                
            
        
    


我正在使用 RxSwift,但主线是:

let urlResponse = response.response as! HTTPURLResponse

您可以在收到响应时将其强制转换到您使用的 map/mapObject/mapArray 中(即Moya.Response

我建议您关注我提出的问题,以了解何时会在包含此 breaking change 的下一个版本中实现它

奖励:如果您在项目中使用 SwiftLint,您可以使用 guard/let 进行转换

guard let resp = response.response as? HTTPURLResponse

【讨论】:

谢谢!添加后我可以获取响应标头,让 urlResponse = response.response 为! HTTPURL响应【参考方案2】:

如果有人在使用 Moya 时仍然对如何获取 url 请求对象感兴趣,这里还有另一个实现:

extension NetworkApiService 
public var urlRequest: URLRequest 
    let defaultURL: URL
    if path.isEmpty 
        defaultURL = baseURL
     else 
        defaultURL = baseURL.appendingPathComponent(path)
    

    let endpoint = MoyaProvider.defaultEndpointMapping(for: self)
    do 
        return try endpoint.urlRequest()
     catch 
        return URLRequest(url: defaultURL)
    


NetworkApiService 符合 Moya 的 TargetType 协议。

请注意,返回的实例与 Moya 引擎调用的 URLRequest 对象并不完全相同,但它是使用 Moya 的 API 实例化的,并且与原始实例具有相同的配置。

【讨论】:

【参考方案3】:

在 Moya 中获取响应头的最简单方法是

switch result 
case let .success(moyaResponse):
     if(moyaResponse.statusCode == 200) 
          let response = moyaResponse.response
          let responseHeaderDictionary = response?.allHeaderFields
     

【讨论】:

以上是关于使用 Moya 获取响应标头的主要内容,如果未能解决你的问题,请参考以下文章

将 Moya 响应错误转换为定义的类型

如何在不发送请求的情况下拦截 Moya 请求并返回失败响应

我可以使用 tcpdump 获取 HTTP 请求、响应标头和响应正文吗?

使用 cURL 仅从 HTTP POST 获取响应标头

AJAX 使用 CORS 获取自定义响应标头

如何从 fetch 中获取响应的标头