Get response header with Moya

后端 未结 3 764
孤城傲影
孤城傲影 2021-01-26 11:54

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

相关标签:
3条回答
  • 2021-01-26 12:11

    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.

    0 讨论(0)
  • 2021-01-26 12:12

    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
         }
    }
    
    0 讨论(0)
  • 2021-01-26 12:20

    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
    
    0 讨论(0)
提交回复
热议问题