2013-04-02 52 views
2

问题:的Facebook的iOS SDK不调用完成处理程序

使用FB SDK和方法openActiveSessionWithReadPermissions,完成处理器似乎并不被调用时,该应用程序从Facebook的网页或Facebook应用程序,我重新打开得到这个错误输出:

FBSDKLog:从FBSessionStateCreated到FBSessionStateClosed FBSDKLog FBSession 无效过渡:FBSession过渡从FBSessionStateCreated到FBSessionStateCreatedOpening

语境

  • 使用Facebook SDK 3.2.1
  • 应用程序是专为iOS 5.0及
  • 测试模拟器上的iOS 5.1
  • 测试的iPhone 4S使用的Xcode 4.6.1 ,运行iOS 6.1.2(不使用6.0社交框架,想测试实现5.0+)
  • 更新最初为iOS 3.0构建的应用程序和u唱一个老版本的sharekit,但现在已经更新了ARC和共享工具包的实现,我相信已经被注释掉了 - 希望这个问题不是与旧的共享工具包功能冲突,不能在代码
  • 采取

步骤来解决搜索整个堆栈溢出

,发现提到类似的问题,但不是一个解决方案

具体细节:

这些是我采取的实施步骤t应用内的Facebook连接。

高层步骤:

  • 我有我的FB方法设立的AppDelegate
  • 在一个特定的视图控制器我有一个按钮,调用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的应用程序到我的帐户的访问,然后尝试再次登录到应用程序,我看到这些已经引起问题与其他用户
+0

好吧,我弄明白了 - 这个问题与FB本身无关,应用程序(我正在更新其他人的代码)在.plist中有一个设置 - '应用程序不在后台运行'设置为true。 这意味着,一旦应用程序从Facebook应用程序或Facebook移动网站重新启动,它就没有准备好处理下一步。 – drc

+0

当我在几个小时内使用stackoverflow时,我会添加这个作为答案。 – drc

+0

嘿DRC,我有同样的错误,但我没有看到“应用程序不在后台运行”.plist中的任何地方。这是应用程序主.plist还是应用程序具有的附加.plist? – SasaT

回答

3

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

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

enter image description here

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/

相关问题