TMC*_*TMC 21 mobile facebook ios facebook-social-plugins facebook-login
在我们的iOS应用程序中,我们有一个UIWebView,在我们的域上显示具有Facebook评论模块的Web内容.评论模块要求用户使用Facebook登录.当用户点击登录按钮时,他们将通过登录流程,但永远不会重定向回我们的页面.他们最终在FB拥有的页面上告诉用户"你现在已登录".
Repro步骤:
登录后(步骤3)我希望在成功验证后,您将被重定向回原始页面(例如http://foo.com/test.htm),以便继续进行交互.但是,这种情况并没有发生.
相反,你在FB拥有的页面上只是说"你现在已经登录"并且你被困在那里.没有重定向发生.
这确实是一个错误,还是我应该做些什么来确保重定向发生?
dth*_*lke 10
如果您只是支持iOS 8及更高版本,您可以使用WKWebView已经实现了@kabuko所描述的功能:
// Container view including the main WKWebView
var container : UIView?
var popupWebView : WKWebView?
override func viewDidLoad() {
super.viewDidLoad()
let prefs = WKPreferences()
prefs.javaScriptEnabled = true
// allow facebook to open the login popup
prefs.javaScriptCanOpenWindowsAutomatically = true
let config = WKWebViewConfiguration()
config.preferences = prefs
webView = WKWebView(frame: container.frame, configuration: config)
webView?.UIDelegate = self
webView?.navigationDelegate = self
}
// callback if the content of the webView wants to create a new window
func webView(webView: WKWebView, createWebViewWithConfiguration configuration: WKWebViewConfiguration, forNavigationAction navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
// create new popup webview and add it to the view hierarchy
popupWebView = WKWebView(frame: container.frame, configuration: configuration)
container.addSubview(popupWebView!)
return popupWebView
}
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
// if the main webView loads a new page (e.g. due to succesful facebook login)
// remove the popup
if (popupWebView != nil) {
popupWebView?.removeFromSuperview()
popupWebView = nil
}
}
Run Code Online (Sandbox Code Playgroud)
我已经看到类似的事情发生在其他网站的FB登录(例如Groupon),如果你加载它们UIWebView.如果这是同样的问题(我认为是这样),那是因为Facebook打开了你怀疑的弹出窗口中的登录窗口.在普通浏览器上发生的事情是打开另一个窗口(弹出窗口)进行登录,然后当用户登录时,该登录窗口会回传到原始窗口,说它已登录.他们可能使用EasyXDM或类似的东西.似乎有几层沟通策略,包括Flash和postMessage.
在iOS(和Android)上,这应该意味着它最终会与之通信postMessage.如果您跟踪通过您的网址,UIWebView您应该会在最后看到类似的内容:
https://s-static.ak.fbcdn.net/connect/xd_proxy.php#<lots of stuff>&relation=opener&transport=postmessage&<lots more stuff>
Run Code Online (Sandbox Code Playgroud)
UIWebView不支持多个窗口,因此它不能再postMessage回到原始页面,因为它已不再加载.您可以做的是检测何时UIWebView尝试加载FB登录页面并将其加载到单独的页面中UIWebView.现在你有两个窗口可以使用.
不幸的是,这仍然不够,因为当FB页面上的JavaScript试图运行window.opener.postMessage或window.parent.postMessage因为window.parent并window.opener没有设置到适当的窗口时它不起作用.我不知道在iOS中这样做的好方法(相比之下,Android为此提供了适当的API).
我解决这个问题的方法是破解一个JavaScript对象来包装这些调用.就像是:
window.opener={};
window.opener.postMessage = function(data,url) {
// signal your code in objective-c using some strategy
};
window.parent = window.opener;
Run Code Online (Sandbox Code Playgroud)
有几种方法可以从JavaScript调用Objective-C,包括官方文档中的这个.您可以将此代码注入我之前提到的静态FB登录页面stringByEvaluatingJavaScriptFromString:.我找不到一个好的时间来做这个,所以我只是在页面加载和调用之后注入它,doFragmentSend()这是静态页面上的FB JavaScript方法,通常在主体加载时被调用.
所以现在我们需要做的就是通过UIWebView调用将这些数据传递给原始数据postMessage.它看起来像这样:
NSString *post = [NSString stringWithFormat:@"window.postMessage('%@', '*');", data];
[webView stringByEvaluatingJavaScriptFromString:post];
Run Code Online (Sandbox Code Playgroud)
如果你现在还没有注意到,这是一个非常混乱的黑客,我可能不会推荐它,除非你别无选择,但它对我有用.
小智 5
我有同样的问题.我想,在Facebook登录后,UIWebView组件为空,其中没有html代码.我通过检查webViewDidFinishLoad函数上的UIWebView组件的内容解决了这个问题,并在我检测到Facebook登录导致白色(空屏幕)时重新加载其内容:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if ( [[webView1 stringByEvaluatingJavaScriptFromString:
@"document.body.innerHTML"] isEqualToString:@""] ) {
[webView1 loadRequest:request]; //Define request as you want
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16432 次 |
| 最近记录: |