-
Notifications
You must be signed in to change notification settings - Fork 722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to setup an async call with the HTTPNetworkTransportPreflightDelegate? #1245
Comments
The same issue goes for setting up subscriptions as the private lazy var webSocketTransport: WebSocketTransport = {
let url = URL(string: "ws://localhost:8080/websocket")!
let request = URLRequest(url: url)
let authPayload = ["authToken": magicToken]
return WebSocketTransport(request: request, connectingPayload: authPayload)
}() |
Sorry I hadn't taken the time to search before opening this- #834 (comment) |
I looked over at the other issue and I still wasn't able to get it solved. My sync function looks like this: func getAccessTokenSync() -> String? {
let semaphore = DispatchSemaphore(value: 0)
var authToken: String?
DispatchQueue.global(qos: .background).async {
self.getAccessToken { (token) in
authToken = token
semaphore.signal()
}
print(authToken)
semaphore.wait()
}
return authToken
} but the authToken returned is always nil. When I don't run on the background thread the app blocks |
Calling it here: func networkTransport(_ networkTransport: HTTPNetworkTransport, willSend request: inout URLRequest) {
var headers = request.allHTTPHeaderFields ?? [String: String]()
let token = Authenticator.shared.getAccessTokenSync() ?? ""
headers["Authorization"] = "Bearer \(token)"
request.allHTTPHeaderFields = headers
log.debug("Sending request with token \(token)")
log.debug("Outgoing request: \(request)")
} |
For the web socket issue we added a way to update the headers in func setupWebSocket(with magicToken: String) -> WebSocketTransport {
// existing code in your lazy getter
}
self.getAccessToken() { token in
let webSocket = self.setupWebSocket(with: token)
// proceed with setting up apollo client
} |
It looks like with your code in this comment you're doing an additional dispatch to a background queue that never calls back to the main queue, so the `wait() may be getting called after the initial method returns. I think if you just ditch the |
Hey, so I have this setup currently: extension Network: HTTPNetworkTransportPreflightDelegate {
func networkTransport(_ networkTransport: HTTPNetworkTransport, shouldSend request: URLRequest) -> Bool {
return true
}
func networkTransport(_ networkTransport: HTTPNetworkTransport, willSend request: inout URLRequest) {
let semaphore = DispatchSemaphore(value: 0)
var authToken: String?
Authenticator.shared.getAccessToken { (token) in
authToken = token
semaphore.signal()
}
print(authToken)
semaphore.wait()
if let token = authToken {
var headers = request.allHTTPHeaderFields ?? [String: String]()
headers["Authorization"] = "Bearer \(token)"
request.allHTTPHeaderFields = headers
}
log.debug("Sending request with token \(authToken ?? "no token")")
log.debug("Outgoing request: \(request)")
}
} however, the callback function is never called for some reason which means the When I remove the |
Ahhh ok that's why you added the What about going back to using the func getAccessTokenSync() -> String? {
let semaphore = DispatchSemaphore(value: 0)
var authToken: String?
DispatchQueue.global(qos: .background).async {
self.getAccessToken { (token) in
authToken = token
semaphore.signal()
}
}
semaphore.wait()
print(authToken)
return authToken
} that starts the |
So far from my basic testing, it’s worked like a charm. I’ll take a more detailed look at it tomorrow but it works as expected. I think adding in a callback to the I’ll probably try to cache the result to prevent having to make that call every time since the value won’t be changing often. |
We're going to be working on changes to the networking stack later in the year that will (hopefully) make this and any other async operation a hell of a lot easier. That said, I think we've addressed your question for the time being, do you mind if we close this issue out? |
Thank you for your help! |
You're welcome! |
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:
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:
which runs the
getAccessToken
in a custom wrapper around theApolloClient.fetch(query)
method and sets it to an instance variable which is then accessed here: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.
The text was updated successfully, but these errors were encountered: