that issue has been fixed now I can fetch response headers below is the solution
let client: ApolloClient = {
// The cache is necessary to set up the store, which we’re going
// to hand to the provider
let cache = InMemoryNormalizedCache()
let store = ApolloStore(cache: cache)
let client = URLSessionClient()
let provider = CustomInterceptorProvider(store: store, client: client)
let url = URL(string: “graphql link”)!
let requestChainTransport = RequestChainNetworkTransport(
interceptorProvider: provider,
endpointURL: url
)
// Remember to give the store you already created to the client so it
// doesn’t create one on its own
return ApolloClient(networkTransport: requestChainTransport, store: store)
}()
struct CustomInterceptorProvider: InterceptorProvider {
private let store: ApolloStore
private let client: URLSessionClient
init(store: ApolloStore, client: URLSessionClient) {
self.store = store
self.client = client
}
func interceptors<Operation: GraphQLOperation>(for operation: Operation) -> [ApolloInterceptor] {
return [
MaxRetryInterceptor(),
CacheReadInterceptor(store: self.store),
NetworkLoggerInterceptor(),
RequestLoggingInterceptor(),
NetworkFetchInterceptor(client: self.client),
ResponseLoggingInterceptor(),
ResponseCodeInterceptor(),
JSONResponseParsingInterceptor(),
AutomaticPersistedQueryInterceptor(),
CacheWriteInterceptor(store: self.store)
]
}
}
final class NetworkLoggerInterceptor: ApolloInterceptor {
public var id: String = UUID().uuidString
func interceptAsync<Operation>(
chain: RequestChain,
request: HTTPRequest<Operation>,
response: HTTPResponse<Operation>?,
completion: @escaping (Result<GraphQLResult<Operation.Data>, Error>) -> Void
) where Operation : GraphQLOperation {
if let token = AccountService.shared.getAccessToken() {
request.addHeader(name: "Authorization", value: "Bearer \(token)")
}
print("Outgoing request: \(request)")
chain.proceedAsync(
request: request,
response: response,
interceptor: self
) { result in
print("Incomming respone :\(result)")
// Handle the Result
switch result {
case .success(let graphQLResult):
completion(.success(graphQLResult))
case .failure(let error):
if let responseCodeError = error as? ResponseCodeInterceptor.ResponseCodeError {
switch responseCodeError {
case .invalidResponseCode(_, let rawData):
self.handleAuthenticationFailure(data: rawData)
}
}else {
self.showrGlobalAlert(errorMessage: error.localizedDescription)
}
}
completion(result)
}
}
private func handleAuthenticationFailure(data: Data?) {
if let finalData = data {
do {
let apiError = try JSONDecoder().decode(APIError.self, from: finalData)
print("Error Message: \(apiError.message)")
print("Error Code: \(apiError.code)")
print("Error Details: \(apiError.details)")
self.showAPIErrorGlobalAlert(apiError)
} catch {
print("Failed to decode error JSON: \(error.localizedDescription)")
}
}
}
private func showAPIErrorGlobalAlert(_ apiError: APIError) {
DispatchQueue.main.async {
if let topController = UIApplication.shared.windows.first?.rootViewController {
if let presentedVC = topController.presentedViewController {
presentedVC.dismiss(animated: true) {
self.showAPIErrorGlobalAlert(apiError)
}
}else {
topController.errorAlert(title: "Error", message: apiError.details)
if apiError.code == "SESSION_EXPIRED" || apiError.code == "UNAUTHENTICATED" || apiError.code == "INVALID_TOKEN" {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.navigateToLoginAfterLogout()
}
}
}
}
}
}
private func showrGlobalAlert(errorMessage: String) {
DispatchQueue.main.async {
if let topController = UIApplication.shared.windows.first?.rootViewController {
if let presentedVC = topController.presentedViewController {
presentedVC.dismiss(animated: true) {
self.showrGlobalAlert(errorMessage: errorMessage)
}
}else {
topController.errorAlert(title: "Error", message: errorMessage)
}
}
}
}
}
class RequestLoggingInterceptor: ApolloInterceptor {
public var id: String = UUID().uuidString
func interceptAsync<Operation: GraphQLOperation>(
chain: RequestChain,
request: HTTPRequest<Operation>,
response: HTTPResponse<Operation>?,
completion: @escaping (Result<GraphQLResult<Operation.Data>, Error>) -> Void
) {
print("Outgoing request: \(request)")
chain.proceedAsync(
request: request,
response: response,
interceptor: self,
completion: completion
)
}
}
class ResponseLoggingInterceptor: ApolloInterceptor {
enum ResponseLoggingError: Error {
case notYetReceived
}
public var id: String = UUID().uuidString
func interceptAsync<Operation: GraphQLOperation>(
chain: RequestChain,
request: HTTPRequest<Operation>,
response: HTTPResponse<Operation>?,
completion: @escaping (Result<GraphQLResult<Operation.Data>, Error>) -> Void
) {
defer {
// Even if we can't log, we still want to keep going.
chain.proceedAsync(
request: request,
response: response,
interceptor: self,
completion: completion
)
}
guard let receivedResponse = response else {
chain.handleErrorAsync(
ResponseLoggingError.notYetReceived,
request: request,
response: response,
completion: completion
)
return
}
if let httpResponse = response?.httpResponse {
self.logResponseDetails(httpResponse: httpResponse)
}
}
private func logResponseDetails(httpResponse: HTTPURLResponse) {
let statusCode = httpResponse.statusCode
let headers = httpResponse.allHeaderFields
if let accessToken = headers["x-access-token"] as? String {
AccountService.shared.setAccessToken(token: accessToken)
}
}
} but In this I am getting response twice in controller can some one help?