In our iOS app, we have a UIWebView that shows web content on our domain that has a Facebook comment module. The comment module requires that the user is signed in with facebook. When user clicks on the sign in button, they are taken through the sign in flow, but are never redirect back to our page. They end up on an FB owned page that just tells the user "You are now signed in".
Repro steps:
- Create a UIWebView in an iOS app, and host a Facebook comment module on a page hosted on some domain you own (e.g. http://foo.com/test.htm).
- Click on the Sign In button on the comment module and notice you are redirect to FB sign in.
- Sign in with valid FB credentials and observe what happens.
After you sign in (step 3) I would expect that after a successful authentication, you are redirected back to the original page (e.g http://foo.com/test.htm) so you can continue your interaction. However, this isn't happening.
Instead, you are on an FB owned page that just says something like "You are now signed in" and you are trapped there. No redirect happens.
Is this indeed a bug or is there something else I should be doing to ensure the redirect happens?
If you are just supporting iOS 8 and up, you can use
WKWebView
which already implements the functionality described by @kabuko:I've seen something similar happen with other sites' FB logins (e.g. Groupon) if you load them in a
UIWebView
. If this is the same problem (which I think it is), it is due to Facebook opening up the login window in a popup as you suspected. What happens on a normal browser is that another window (popup) is opened for login, and then when the user logs in, that login window communicates back to the original window to say that it has logged in. They probably use EasyXDM or something similar. There seem to be a few layers of strategies to communicate including Flash andpostMessage
.On iOS (and Android) this should mean it'll end up communicating with
postMessage
. If you track the URLs that go through yourUIWebView
you should see something like this near the end:UIWebView
doesn't support multiple windows so it can'tpostMessage
back to your original page since it's no longer loaded. What you can do is detect when theUIWebView
is trying to load the FB login page and load that in a separateUIWebView
. Now you have two windows to work with.Unfortunately, this is still not enough as when the JavaScript on FB's page tries to run
window.opener.postMessage
orwindow.parent.postMessage
it doesn't work becausewindow.parent
andwindow.opener
aren't set to the appropriate window. I don't know of a good way to do this in iOS (in contrast Android provides a proper API for this).The way I've worked around this is to hack up a JavaScript object to wrap these calls. Something like:
There are a few ways you can call Objective-C from JavaScript including this one from the official docs. You can inject this code into that static FB login page I mentioned before using
stringByEvaluatingJavaScriptFromString:
. I couldn't find a good time to do this, so I just inject it after page load and calldoFragmentSend()
which is the FB JavaScript method on that static page that normally gets called on body load.So now all we need to do is pass on this data into the original
UIWebView
by callingpostMessage
. It'll look something like this:If you haven't noticed by now, this is a huge messy hack and I probably wouldn't recommend it unless you have no alternative, but it's worked for me.
Currently in mobile, browser not supporting multiple windows by default. The alternate solution is to monitor the successful redirect from facebook like "close_popup.php?reload=https://" and reloading the page. Also make sure that you preserve the facebook comment value before login request so that it can be again put in comment box.
I had the same problem. I figured out, after the Facebook login the UIWebView components is empty, there is no html code within it. I solved the issue by checking the content of the UIWebView component on the webViewDidFinishLoad function and reload its content when I detect the Facebook login causes white (empty screen):