Facebook 浏览器登录重定向到应用程序后不会调用处理程序

Handler does not get called after Facebook Browser Login redirects to Application

我在我的应用程序中使用 Facebook SDK v4.8.0 for iOS 登录 Facebook。 (iPhone OS 版本 9.3)

下面是一些相关的集成代码:

AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
    return true
}

func applicationDidBecomeActive(application: UIApplication) {
    FBSDKAppEvents.activateApp()
}

func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {    
        return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}

func application(application: UIApplication, openURL url: NSURL, options: [String: AnyObject]) -> Bool {
        return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url,
                                                                     sourceApplication: "UIApplicationOpenURLOptionsSourceApplicationKey",
                                                                     annotation: "UIApplicationOpenURLOptionsAnnotationKey")
}

Login.Swift

@IBAction func btnFacebook(sender: UIButton) {

    self.loginToFacebookWithSuccess({ (response) -> Void in
        print("Success")
    }) { (error) -> Void in
        print("failure")
    }

func loginToFacebookWithSuccess(successBlock: () -> (), andFailure failureBlock: (NSError?) -> ()) {

    let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
    fbLoginManager.loginBehavior = .SystemAccount

    FBSDKLoginManager().logInWithReadPermissions(["public_profile", "email", "user_friends"], fromViewController: self, handler: { (result:FBSDKLoginManagerLoginResult!, error:NSError!) -> Void in

        if error != nil {
            print("error")
        } else if result.isCancelled {
            print("cancelled")
        } else {
            print("worked fine") // get Facebook user data here
        }
    })
}

当用户未在设备中配置 Facebook 帐户时,应用程序转到浏览器并提供 Facebook 登录 UI。一旦用户完成登录,浏览器就会重定向到应用程序。至此一切正常。

问题

当浏览器将用户重定向到 App 时,没有任何反应。 (没有调用成功或失败的处理程序)。为了防止用户在浏览器中点击 "Done","cancelled" 会打印在日志中。但是,对于 "cancel" 或 "okay"(或者说 "Continue as Username"),重定向后没有任何反应。

有什么线索吗?

如果我遗漏了任何信息,请告诉我。

application(application: UIApplication, openURL url: NSURL, options: [String: AnyObject]) 方法中,您传入 sourceApplicationannotation 参数硬编码字符串。

我认为这就是问题所在。尝试使用静态键 UIApplicationOpenURLOptionsSourceApplicationKeyUIApplicationOpenURLOptionsAnnotationKey.

传递 options 字典中的值 您还应该需要在方法声明之前添加 @available(iOS 9.0, *) 因为它仅适用于 iOS 9.

最终函数应该是这样的:

@available(iOS 9.0, *)
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
   return FBSDKApplicationDelegate.sharedInstance().application(app, openURL: url, sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as! String, annotation: options[UIApplicationOpenURLOptionsAnnotationKey])
}

我建议使用 Facebook 方法并实施他们的 FBSDKLoginButton。设置按钮 facebookButton.readPermissions = ["email", "user_birthday", "public_profile"] 的读取权限。并委托给 viewController.

//MARK:- FBSDKLogin Button Delegate
extension LoginViewController: FBSDKLoginButtonDelegate {

    func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {

        guard let response = result, let _ = response.token else {
            createAlertController("Error", message: "There was a problem with the Facebook login. Please try again.")
            return
        }

        //Do what ever you need here
    }

    func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
        //Required method, we don't need it at login screen
    }
}

确保您遵循所有 Facebook plist 设置信息。 iOS 9+

的应用程序传输安全

我认为您的打开 url 方法需要进行以下更改:

func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any]) -> Bool {

    let isFBURL = ((url.scheme?.hasPrefix("fb\(FBSDKSettings.appID()!)"))! && url.host == "authorize")

    if  isFBURL == true {

        return FBSDKApplicationDelegate.sharedInstance().application(application, open: url,
                                                                     sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
                                                                     annotation: options[UIApplicationOpenURLOptionsKey.annotation] as? String)
    }
}

如果可行,请告诉我。