Skip to content

How to setup an async call with the HTTPNetworkTransportPreflightDelegate? #1245

@ingeniousgenius

Description

@ingeniousgenius

I'm currently trying to set up token authentication with the Apollo iOS library. I've looked through the docs here which suggests the following code:

extension Network: HTTPNetworkTransportPreflightDelegate {
  func networkTransport(_ networkTransport: HTTPNetworkTransport, 
                        willSend request: inout URLRequest) {
                        
    // Get the existing headers, or create new ones if they're nil
    var headers = request.allHTTPHeaderFields ?? [String: String]()

    // Add any new headers you need
    headers["Authorization"] = "Bearer \(UserManager.shared.currentAuthToken)"
  
    // Re-assign the updated headers to the request.
    request.allHTTPHeaderFields = headers
    
    Logger.log(.debug, "Outgoing request: \(request)")
  }
}

The issue I'm having is that my currentAuthToken method requires a callback since it's asynchronous and in the example given the code is synchronous.

Right now, my "hacky" workaround is to do something like this:

class Network {
// Other irrelevant stuff
  var accessToken: String?

func query<Query: GraphQLQuery>(_ query: Query,
    cachePolicy: CachePolicy = .returnCacheDataElseFetch,
    queue: DispatchQueue = .main,
    handler: GraphQLResultHandler<Query.Data>? = nil
  ) {
   // The asynchronous call
    Authenticator.shared.getAccessToken { [weak self] (token) in
      self?.accessToken = token
      self?.apollo.fetch(query: query, cachePolicy: cachePolicy, queue: queue, resultHandler: handler)
    }
  }

which runs the getAccessToken in a custom wrapper around the ApolloClient.fetch(query) method and sets it to an instance variable which is then accessed here:

func networkTransport(_ networkTransport: HTTPNetworkTransport, willSend request: inout URLRequest) {
    var headers = request.allHTTPHeaderFields ?? [String: String]()
    headers["Authorization"] = "Bearer \(accessToken ?? "")"
    request.allHTTPHeaderFields = headers
    
    log.debug("Sending request with \(accessToken ?? "no token")")
    log.debug("Outgoing request: \(request)")
  }

I'm not sure if this is the best solution, but I have tried it so far and it works as expected. If there could be any clarity regarding this that would be great.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions