2

问题:

使用 FB SDK 和 openActiveSessionWithReadPermissions 方法,当应用程序从 Facebook 网络或 Facebook 应用程序重新打开时,完成处理程序似乎不会被调用,并且我得到以下错误输出:

FBSDKLog:从 FBSessionStateCreated 到 FBSessionStateClosed 的 FBSession INVALID转换 FBSDKLog:从 FBSessionStateCreated 到 FBSessionStateCreatedOpening 的 FBSession 转换

语境

  • 使用 Facebook SDK 3.2.1
  • 应用程序是为 iOS 5.0+ 构建的
  • 使用 xCode 4.6.1
  • 在模拟器 iOS 5.1 上测试
  • 在 iPhone 4S 上测试,运行 iOS 6.1.2(不使用 6.0 社交框架,因为想要测试 5.0+ 的实现)
  • 更新最初为 iOS 3.0 构建的应用程序并使用旧版本的 sharekit,但现在已针对 ARC 进行了更新,并且我相信共享工具包实现已全部被注释掉 - 希望问题不是与旧共享工具包冲突函数,在代码中找不到任何

为解决而采取的步骤

搜索整个 Stack Overflow,发现提到的类似问题,但不是解决方案

规格:

这些是我在应用程序中实现 Facebook 连接所采取的步骤。

  • 我采取的第一步是浏览 Facebook 教程:https ://developers.facebook.com/docs/tutorials/ios-sdk-tutorial/ 。我得到了第一部分,身份验证部分按预期工作(我按照教程的指示构建了一个单独的应用程序。)
  • 然后我在我正在更新的应用程序的教程中采取了相同的步骤,这不起作用
  • 然后我按照https://developers.facebook.com/docs/howtos/login-with-facebook-using-ios-sdk/上的说明进行操作(与教程非常相似)
  • 我又遇到了问题
  • 然后花了很多时间寻找解决方案,找不到一个

代码中的高级步骤:

  • 我在 AppDelegate 中设置了我的 FB 方法
  • 在特定的视图控制器中,我有一个按钮,它调用 openSessionWithAllowLoginUI 方法来启动登录过程

代码

AppDelegate.m

- (void)applicationDidFinishLaunching:(UIApplication *)application 
{   
// set up facebook logging
    [FBSettings setLoggingBehavior:[NSSet setWithObjects:FBLoggingBehaviorFBRequests, FBLoggingBehaviorFBURLConnections, FBLoggingBehaviorAccessTokens, FBLoggingBehaviorSessionStateTransitions, nil]];

    // Call the ACAccountStore method renewCredentialsForAccount, which will update the OS's understanding of the token state
    ACAccountStore *accountStore;
    ACAccountType *accountTypeFB;
    if ((accountStore = [[ACAccountStore alloc] init]) &&
        (accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook] ) ){

        NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];
        id account;
        if (fbAccounts && [fbAccounts count] > 0 &&
            (account = [fbAccounts objectAtIndex:0])){

            [accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
                //we don't actually need to inspect renewResult or error.
                if (error){

                }
            }];
        }
    }

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // We need to properly handle activation of the application with regards to Facebook Login
    // (e.g., returning from iOS 6.0 Login Dialog or from fast app switching).
    NSLog(@"Calling app did become active");
    [FBSession.activeSession handleDidBecomeActive];
}

/*
 * Callback for session changes.
 */
- (void)sessionStateChanged:(FBSession *)session
                      state:(FBSessionState) state
                      error:(NSError *)error
{
    NSLog(@"Session State Changed");

    switch (state) {
        case FBSessionStateOpen:
            if (!error) {
                // We have a valid session
                NSLog(@"User session found");
            }
            break;
        case FBSessionStateClosed:
        case FBSessionStateClosedLoginFailed:
            [FBSession.activeSession closeAndClearTokenInformation];
            break;
        default:
            break;
    }

    [[NSNotificationCenter defaultCenter]
     postNotificationName:FBSessionStateChangedNotification
     object:session];

    if (error) {
        UIAlertView *alertView = [[UIAlertView alloc]
                                  initWithTitle:@"Error"
                                  message:error.localizedDescription
                                  delegate:nil
                                  cancelButtonTitle:@"OK"
                                  otherButtonTitles:nil];
        [alertView show];
    }
}

/*
 * Opens a Facebook session and optionally shows the login UX.
 */
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
    NSLog(@"Openning session with Facebook");
    return [FBSession openActiveSessionWithReadPermissions:nil
                                              allowLoginUI:allowLoginUI
                                         completionHandler:^(FBSession *session,
                                                             FBSessionState state,
                                                             NSError *error) {
                                             [self sessionStateChanged:session
                                                                 state:state
                                                                 error:error];
                                         }];
}


/*
 * If we have a valid session at the time of openURL call, we handle
 * Facebook transitions by passing the url argument to handleOpenURL
 */
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    // attempt to extract a token from the url
    NSLog(@"Calling open URL");
    return [FBSession.activeSession handleOpenURL:url];
}

- (void) closeSession {
    NSLog(@"Clossing Facebook Sessions");
    [FBSession.activeSession closeAndClearTokenInformation];
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    NSLog(@"handleOpenUrl Called");
    return [FBSession.activeSession handleOpenURL:url];

}

使用按钮查看控制器

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    // Register for Facebook change notification
    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(sessionStateChanged:)
     name:FBSessionStateChangedNotification
     object:nil];
}

- (IBAction)login:(id)sender {
    ATIAppDelegate *myAppDelegate = (ATIAppDelegate *)[[UIApplication sharedApplication]delegate];
     [myAppDelegate openSessionWithAllowLoginUI:YES];
}

我认为问题可能是什么?

  • 似乎它可能与令牌有关?
  • 或者也许是通知中心?
  • 请注意,在测试期间,我一直在撤销 Facebook 应用程序对我的帐户的访问权限,然后尝试再次登录该应用程序,我发现这些已导致其他用户出现问题
4

2 回答 2

3

好的,我想通了 - 问题与 FB 本身无关,应用程序(我正在更新其他人的代码)在 .plist 中有一个设置 - '应用程序不在后台运行'设置为 true。

这意味着一旦应用程序从 Facebook 应用程序或 Facebook 移动网站重新启动,它就没有准备好处理下一步。

在此处输入图像描述

于 2013-04-03T12:54:45.000 回答
0

如果您不希望应用程序在后台运行,您可以FBSDKApplicationDelegate像这样绑定到 AppDelegate 中的 :

import UIKit
import FBSDKLoginKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    func applicationWillResignActive(_ application: UIApplication) {
        FBSDKAppEvents.activateApp()
    }

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        return FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
    }
}

https://forums.developer.apple.com/thread/50332 http://ashishkakkad.com/tag/fbsdkapplicationdelegate/

于 2017-01-09T23:14:23.673 回答