ios - 保持同一 session FBSDKLoginKit、FBSDKShareKit 4.36

标签 ios swift authentication fbsdkloginkit fbsdksharedialog

我正在使用 FBSDKLoginKit 和 FBSDKShareKit 进行登录,并在共享 FBSDKShareOpenGraphContent 后进行。

我在 Android 中也有类似的行为,并且运行良好。

很快我就能够在 Facebook 中成功登录,但是当我调用 FBSDKShareDialog.show(from: self, with: content, delegate: nil) 从详细 View Controller 共享我的 FBSDKShareOpenGraphContent 时,应用程序显示登录 FACEBOOK 页面再次在浏览器中! 我以为FBSDKShareOpenGraphContent是直接分享的,不需要再次登录!

如果 FBSDKAccessToken.currentAccessTokenIsActive() 返回 true,为什么会出现此行为? 如何在不同的 View Controller 之间保持相同的 session ? 我阅读了数十亿篇有关它的帖子,但这些解决方案并不能解决我的问题

请注意,如果我第二次输入用户名和密码并重新登录,FBSDKShareOpenGraphContent 会正确共享! 但这是一个糟糕的用户体验,我希望用户只能登录一次!

请帮忙 这是我的代码:

//APPDELEGATE

      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
                // Override point for customization after application launch.

                FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
                          return true
            }

            private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
                // Override point for customization after application launch.
                return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
            }

            private func application(application: UIApplication, openURL url: URL, sourceApplication: String?, annotation: Any?) -> Bool {
                return FBSDKApplicationDelegate.sharedInstance().application(
                    application,
                    open: url as URL?,
                    sourceApplication: sourceApplication,
                    annotation: annotation)
            }
    func applicationDidBecomeActive(_ application: UIApplication) {
            // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
            FBSDKAppEvents.activateApp()
        }

    ----

//登录 VIEWCONTROLLER @IBAction

    @IBAction func fbLoginButtonTapped(_ sender: UIButton) {
            let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
            fbLoginManager.logIn(withReadPermissions: ["public_profile"], from: self) { (result, error) -> Void in
                if (error == nil) {

                    let fbloginresult : FBSDKLoginManagerLoginResult = result!
                    // if user cancel the login
                    if (result?.isCancelled)! {
                        print("LOGIN FB CANCELLED")
                        return
                    }
                    if(fbloginresult.grantedPermissions.contains("public_profile")) {
                        print("LOGIN FB SUCCESS")
                        /* DO MY STUFF */   
                    }
                } else {
                    print("LOGIN FB ERROR")
                }
            }
        }

   //Page Detail ViewController with share button @IBAction

     @IBAction func facebookButtonTapped(_ sender: UIButton) {
                if (FBSDKAccessToken.currentAccessTokenIsActive() == true) {
//THIS RETURNS TRUE AS USER IS ALWAYS LOGGED

                    let properties = ["og:type": "article",
                                      "og:title": "\(self.post?.title ?? "")",
                        "og:image": "\(self.post?.image ?? "")",
                        "og:description": "\(self.post?.content ?? "")"]

                    let object: FBSDKShareOpenGraphObject = FBSDKShareOpenGraphObject(properties: properties)

                    let action: FBSDKShareOpenGraphAction = FBSDKShareOpenGraphAction(type: "news.reads", object: object, key: "article")
                    let content: FBSDKShareOpenGraphContent = FBSDKShareOpenGraphContent()
                    content.action = action
                    content.previewPropertyName = "article"
                    FBSDKShareDialog.show(from: self, with: content, delegate: nil)
                }
        }

用于 Facebook 集成的 Info.plist

 <!-- FBSDK INTEGRATION -->
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>fb************</string>
            </array>
        </dict>
    </array>
    <key>FacebookAppID</key>
    <string>**************</string>
    <key>FacebookDisplayName</key>
    <string>*********</string>

    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>fbapi</string>
        <string>fb-messenger-api</string>
        <string>fbauth2</string>
        <string>fbshareextension</string>
    </array>

First Login page shown after login button tapped:

Login page again on share button tapped, after first login success

最佳答案

我用以下代码解决了这个问题:

 let shareDialog = FBSDKShareDialog()
 shareDialog.delegate = self
shareDialog.shareContent = content

if (UIApplication.shared.canOpenURL( URL(string: "fbauth2:/")!) ) {
    shareDialog.mode = .native
} else {
    shareDialog.mode = .web
}

shareDialog.show()

以前我用过

shareDialog.mode = .auto

但是,如果这无法选择适当的操作或由于某种原因失败,则似乎会重新实例化网络浏览器而不保持事件 session 。

通过 .native 和 .web 模式,我可以处理已安装或未安装 native 应用程序的情况,保持事件 session 。

关于ios - 保持同一 session FBSDKLoginKit、FBSDKShareKit 4.36,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52343898/

相关文章:

ios - UIInterpolatingMotionEffect 视差效果 Swift 2 iOS

java - 如何配置 ldaptive 以使用连接池 (jaas)

php - 在 JSON Web 服务中验证和跟踪用户

ios - 检查NSString是有效数字-整数还是十进制数字

ios - 如何在不使用框架的情况下快速创建 RequestManager 类

ios - 从 AppDelegate 到 PresentedViewController 的警报 : "Attempt to present UIAlertController on ... whitch is already presenting UIAlertController"

objective-c - 如何将音频数据存储到文档目录中?

Java HTTP PUT 与 Java 中的摘要式身份验证

iphone - 当硬件音量开关关闭时,无论关闭如何检测关闭状态并播放音频的任何方式。

ios - 如何将 Thrift 0.12 导入 Xcode 以支持 Swift 4.2