I am developing an iOS application (using AFNetworking 2, AFURLSessionManager) where I have to interact with an API that I don't control (which is using the Symfony PHP framework if that makes any difference).
The problem is this: The user has an account. On app's first launch, the user gets a form-based login screen. They log in, then get a session cookie. The cookie expires in 30 minutes. It will renew itself on every call that the client makes. HOWEVER, if the app is restarted the cookie is deleted and if the app is idle for more than 30 mins, the cookie will become invalid.
I have multiple difficulties here. First of all, I need to make the login call transparently, so the user doesn't have to re-login. So I get the error response and I make the login request and on success I remake the original request. Now the problem is that there could be several simultaneous requests happening, and couple that with the unreliable nature of mobile network connections. So what happens with this logic seems like a nightmare of multiple logins and retries and lots of extra code and error handling.
My solution so far is this: Make a request. If I get an unauthorized error response, add the request to a retry queue (that I manage myself), set a login flag, and make the login request. Any new requests that come in first check the login flag, to see if there is a login in progress. If so, they go directly to the retry queue. When the login request is complete, I go through the retry queue and make all the queued requests.
So far, this seems to be working pretty well. BUT, I have this nagging feeling that there has to a better way. Are there no built-in mechanisms to deal with this kind of situation? It seems like a common way to handle user authentication, but I can't find any documentation about how to deal with this in AFNetworking. They cover Basic and Digest auth but nothing about this form-based session cookie auth. This is the first time I have to deal with this and I just can't believe that no one else has had this exact same problem. Any ideas?