3lvis / Networking

Swift HTTP Networking with stubbing and caching support
MIT License
1.36k stars 112 forks source link

Token Refresh #216

Closed codeOfRobin closed 4 years ago

codeOfRobin commented 7 years ago

Hey Elvis! 👋

I had a few questions around token refresh? What'd be a good way to detect if any request fails, initiate a token refresh, then retry all the requests that failed? (Similar to Alamofire's session retrial

3lvis commented 7 years ago

HiI! Right now we only have "unauthorizedRequestCallback", it gets called when a 403 is triggered so you can renew your token.

https://github.com/3lvis/Networking/blob/master/Sources/Networking.swift#L169

I think we could do better, though. What are your thoughts on the current solution?

codeOfRobin commented 7 years ago

🤔 Is it called for all requests? If so, In theory, you could put in a couple of NSLocks and initiate retrials for all the requests after getting a new token, right?

3lvis commented 7 years ago

That could work 🤔.

I guess that's the biggest missing piece at the moment, the retrials after the token part. I guess ideally you have all the requests in a queue and if you get a 403, you stop all the requests in the queue until the token is renewed, then you restart the pending requests.

codeOfRobin commented 7 years ago

all the requests in a queue

You mean in a concurrent queue, correct? Doesn't URLSession do that by default?

3lvis commented 7 years ago

We could probably use that one

https://developer.apple.com/documentation/foundation/urlsession/1411597-init

codeOfRobin commented 7 years ago

@3lvis how about we have a post and a pre-response hook for all requests? That way, you don't execute a completion block (like in https://github.com/3lvis/Networking/blob/master/Sources/Networking%2BHTTPRequests.swift#L13 )

until the post commit hook is completed. If you have a 401 with an expired token, execute a lock.lock*(), and refresh your tokens. Once your token is refreshed, retry the request (not quite sure how you'd do that)

I've also been considering implementing this an Rx extension to Networking (imagine having a shared observable and every request using the retry operator with it. It could also be used in conjunction with Rx's smart retry policies