Get response header with Moya

2020-05-09 03:16发布

I am using Moya in my swift app for network requests.

I am able to get requests and map the result using Moya- Object Mapper.

I have used alamofire earlier and I am familiar with how to make post, get requests and read the response headers .

However, I can't seem to understand how I can do the same in Moya.

I did go through the documentation but it does not say anything about reading response headers.

Is there any example or tutorial where I can follow how to do a HTTP authentication and read the response headers. And also on how I can make post requests and send parameters as field parameters or json body.

I have already gone through the Moya example.

Any help will be appreciated. Thank you.

3条回答
爱情/是我丢掉的垃圾
2楼-- · 2020-05-09 03:58

Response header in Moya is in fact quite hard for the moment. It's a unwanted old downcast in Moya code. I never know why they downcasted it.

I opened a related issue to point it out: Moya header

And do some change thanks to a pull request: Moya header PR

This is an example of my personal code where I forcecast the response to get access to the headers:

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)
                }
            }
        }
    }

}

I'm using RxSwift but the main line is:

let urlResponse = response.response as! HTTPURLResponse

You may forcecast it in your map/mapObject/mapArray you use when you get the response (which is a Moya.Response)

I suggest to you to follow the issue I made, to know when it will be implemented in the next release which will contain this breaking change

Bonus: if you use SwiftLint in your project, you may cast it with a guard/let

guard let resp = response.response as? HTTPURLResponse
查看更多
Evening l夕情丶
3楼-- · 2020-05-09 04:05

If anyone still interested how to get url request object when using Moya, here is yet another implementation:

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)
    }
}
}

Where NetworkApiService conforms to Moya's TargetType protocol.

Please take a note, that returned instance is not exactly same URLRequest object that called by Moya's engine, but it is instantiated using Moya's API and will have same configuration as original one.

查看更多
虎瘦雄心在
4楼-- · 2020-05-09 04:08

The easiest way to get response headers in Moya is

switch result {
case let .success(moyaResponse):
     if(moyaResponse.statusCode == 200) {
          let response = moyaResponse.response
          let responseHeaderDictionary = response?.allHeaderFields
     }
}
查看更多
登录 后发表回答