Parse.com Facebook 授权从不调用完成处理程序

Posted

技术标签:

【中文标题】Parse.com Facebook 授权从不调用完成处理程序【英文标题】:Parse.com Facebook authorize never calls completion handler 【发布时间】:2014-12-31 00:00:21 【问题描述】:

我的应用程序即将完成,我们决定允许用户使用 Facebook 登录。

在过去的某个时候,此功能可以正常工作,但现在它只是挂起。

我已包含最新的 Parse SDK (1.6.1) 和最新的 Facebook SDK (3.21.1)。

我认为我已正确设置应用程序。以下是我正在拨打的电话:

// AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    [Parse setApplicationId:@"appId" clientKey:@"clientKey"];
    [PFFacebookUtils initializeFacebook];
    return YES;

- (void)applicationDidBecomeActive:(UIApplication *)application 
    [FBAppCall handleDidBecomeActiveWithSession:[PFFacebookUtils session]];

- (void)applicationWillTerminate:(UIApplication *)application 
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    [[PFFacebookUtils session] close];

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 
    return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication withSession:[PFFacebookUtils session]];


// Login View Controller
- (void)loginWithFacebok 
    [PFFacebookUtils logInWithPermissions:@[@"public_profile", @"email"] block:^(PFUser *user, NSError *error) 
        if (error != nil) 
            // Error handling here.

         else 
            if (user == nil) 
                // Something odd happened; error handling here.

             else 
                // A further Facebook method...
                [self authorizeFacebookPublish];
            
        
    ];

基本上,虽然它在以前可以工作,但现在它不再起作用,因为block 从未被调用过。我确实将“应用程序跳转”到 Facebook 应用程序/网页(现在不记得是哪个了,因为我已经批准了,所以它“跳转”到那里并返回的速度太快了,我无法判断这是过去的)。有趣的是,如果我强制退出应用程序(应用程序基本上处于“挂起”状态)并重新启动应用程序,应用程序会加载并且用户已登录。

这是相当重要的一点,但我找不到其他人遇到这个特殊问题。

我看到了this question,但我们没有使用 Twitter。

This question 与 Parse 无关。


编辑: 我正在努力解决这个问题,并且对断点捕获感到有些困惑。例如,在我的-loginWithFacebook 方法中,我在第一行(loginWithPermissions 调用)返回块的第一行(if (error != nil) ...)放置了一个断点,第一个断点将每次都被击中两次。我终于想尝试一些新的东西,所以我在第一行上方添加了一个NSLog 行并将第一个断点移到那里。随后的运行有第一个断点(现在在@ 987654330@) 命中一次,然后块的第一行命中第二次。因此,我能够确定我的问题是不是,实际上是在我的loginWithFacebook方法中。它在我的@ 987654332@ 方法。代码如下:
- (void)authorizeFacebookPublish 
    NSLog(@"authorizing for Facebook publish..."); // First breakpoint here...
    [PFFacebookUtils reauthorizeUser:[PFUser currentUser]
              withPublishPermissions:@[@"publish_actions"]
                            audience:FBSessionDefaultAudienceFriends
                               block:^(BOOL succeeded, NSError *error) 
                                   if (error != nil)  // Second breakpoint here...
                                       // Error handling...

                                    else 
                                       if (succeeded == YES) 
                                           // Our app now has publishing permissions for the user
                                           [PFUser currentUser][@"canPublishToFacebook"]    = @(YES);

                                        else 
                                           // Our app was refused publishing permissions
                                           [PFUser currentUser][@"canPublishToFacebook"]    = @(NO);

                                           [[PFUser currentUser] saveInBackground];                                           
                                       
                                       // Log in was successful, so do other stuff.... 
                                                                  
                               ];

我现在看到了here 中也列出的问题,即某个断点(显然每次都被称为“断点 2.1”)。然而,这个人并没有报告我看到的同样的问题,即返回块永远不会触发。因此,我的结论是授权(或者可能是重新授权)块中存在一些问题。

正如我上面提到的,这段代码在过去的某个时候工作过。 “重新授权”是否可能导致错误?有没有办法让我检查用户过去是否已经授权我的应用程序并跳过授权过程(因为它已经完成了)?如果这问题,那么在用户注销后(使用 Facebook)重新登录的正确程序是什么?

【问题讨论】:

你确定完成块没有运行吗?如果您注释掉“[self authorizeFacebookPublish];”会发生什么? 您是否从委托中的 handleOpenURL 返回 YES?我想你做到了。 @LyndseyScott 我在完成块的第一行有一个断点。我的代码再也不会到达[self authorizeFacebookPublish] @Harry 是的。或者至少,我认为return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication withSession:[PFFacebookUtils session]]; 就是这样做的。正如我在帖子中提到的,该应用程序确实会从 Facebook 的应用程序/网页返回和返回,所以我不认为这就是问题所在。 尝试在 if(error != nil) 行之前记录 usererror 的值并告诉我。 【参考方案1】:

首先,你为什么在你的 applicationWillTerminate: 回调中调用 [[PFFacebookUtils session] close] ? Facebook 会话使用存储在磁盘上的令牌,这意味着会话在应用程序启动时保持打开状态,并且在应用程序终止时没有理由关闭。

如果你想注销用户,你应该调用[PFUser logOut],然后是[[PFFacebookUtils session] close],或者更好的是[[PFFacebookUtils session] closeAndClearTokenInformation](但我不确定这是否有必要)。 如果您不想注销用户(我认为这更好),请不要调用任何内容。

其次,我过去在[PFFacebookUtils reauthorizeUser: ...] 上也遇到过很多问题。我发现的一种解决方法是直接使用 Facebook API:

[[PFFacebookUtils session] requestNewPublishPermissions:[NSArray arrayWithObject:@"publish_actions"] defaultAudience:FBSessionDefaultAudienceFriends completionHandler:^(FBSession *session, NSError *error) 
    if (!error) 
        if ([[PFFacebookUtils session].permissions indexOfObject:@"publish_actions"] == NSNotFound) 
            // Permission not granted, tell the user we will not share to Facebook
            NSLog(@"Permission not granted, we will not share to Facebook.");
         else 
            // Permission granted.
        
     else 
        // An error occurred. See: https://developers.facebook.com/docs/ios/errors
        NSLog(@"Error : Requesting \"publish_actions\" permission failed with error : %@", error);
    
];

它的作用完全相同,但似乎效果更好。

另外,关于你的多个断点问题,如果你在一个块的开头放置一个断点,它通常会停止两次:创建块时和调用块时。该块只被调用一次,您可以像以前一样使用NSLog(...) 调用来检查它。

【讨论】:

感谢您的帮助。我目前正在测试您的答案,但我认为它对我有用!如果它持续通过一些测试,我会回来接受你的回答。在回答您关于我为什么在applicationWillTerminate: 中调用[[PFFacebookUtils session] close] 的问题时,这是this page 上Parse 推荐 的模式。我需要做一些进一步的调查,看看在我的场景中是否有必要/可取。 你是对的,感谢您指出这一点!我想知道为什么,这对我来说似乎很奇怪,但也许有一个原因...... 经过深思熟虑,我假设这是一个非常安全的应用程序,需要用户在每次应用程序启动时重新登录。但是,我也希望同时致电[PFUser logOut]。我真的不知道如何“按原样”处理代码,现在 Parse 没有真正的支持论坛......我不知道,我想我现在会留下这个问题。

以上是关于Parse.com Facebook 授权从不调用完成处理程序的主要内容,如果未能解决你的问题,请参考以下文章

Facebook 登录 Parse.com 的最低权限

如何使用 Parse.com 登录获取 Facebook 用户电子邮件

使用 Parse.com iOS 获取 Facebook 好友

通过 Facebook iOS Parse.com 登录用户

Parse.com 和 Facebook SDK 问题

facebook 登录是不是要求我在我的应用程序中使用 PFUser(使用 parse.com)?