Facebook iOS SDK未调用完成处理程序

时间:2013-04-02 21:56:23

标签: ios facebook facebook-ios-sdk

问题:

使用FB SDK和方法openActiveSessionWithReadPermissions,当从Facebook web或Facebook应用程序重新打开应用程序时,似乎没有调用完成处理程序,我得到此错误输出:

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

上下文

  • 使用Facebook SDK 3.2.1
  • App适用于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连接的步骤。

代码中的高级步骤:

  • 我在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应用访问我的帐户,然后尝试再次登录该应用,我看到这些已经导致其他用户出现问题

2 个答案:

答案 0 :(得分:3)

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

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

enter image description here

答案 1 :(得分:0)

如果您不希望该应用在后台运行,您可以绑定到AppDelegate中的FBSDKApplicationDelegate,如下所示:

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/