【问题标题】:Facebook iOS SDK 3.5.1: openActiveSessionWithReadPermissions - completion handler called twiceFacebook iOS SDK 3.5.1:openActiveSessionWithReadPermissions - 完成处理程序调用两次
【发布时间】:2013-05-17 05:14:09
【问题描述】:

我有一个分享链接的按钮。我基本上使用了两个电话: openActiveSessionWithReadPermissionsrequestNewPublishPermissions

所以这是按钮操作:

- (IBAction) shareFacebookButtonAction:(id)sender
if (![[FBSession activeSession] isOpen])
        {
            NSArray *permissions = @[@"read_friendlists", @"email"];
            [FBSession openActiveSessionWithReadPermissions:permissions
                                               allowLoginUI:YES
                                          completionHandler:^(FBSession *session,
                                                              FBSessionState state,
                                                              NSError *error)
             {
                 if (FB_ISSESSIONOPENWITHSTATE([session state]))
                 {
                     [self _prepareShare];
                 }
                 else
                 {
                     // show alert view with error
                 }
             }];
        }
        else
        {        
            [self _prepareShare];
        }
    }

如果在会话中没有找到权限,我请求发布权限

-(void) _prepareShare;
{
    if ([FBSession.activeSession.permissions
         indexOfObject:@"publish_actions"] == NSNotFound)
    {
        [FBSession.activeSession
         requestNewPublishPermissions:
         [NSArray arrayWithObject:@"publish_actions"]
         defaultAudience:FBSessionDefaultAudienceFriends
         completionHandler:^(FBSession *session, NSError *error)
         {
             if (!error)
             {
                 [self _share];
             }
             else
             {
                 //error
             }
         }];
    } else
    {
       [self _share];
    }
}

_share 只是发布一些东西

-(void) _share;
{

    NSMutableDictionary *params_dict = [NSMutableDictionary dictionary];
    // setting some params

    [FBRequestConnection startWithGraphPath:@"me/feed" parameters:params_dict HTTPMethod:@"POST" completionHandler:^(FBRequestConnection *connection, id result, NSError *error)
    {
        if (result)
        {
            // sharing succedeed, do something
        }
        else if (error)
        {
            //sharing failed, do something else
        }
    }];
}

我第一次尝试分享openActiveSessionWithReadPermissions 的完成处理程序(已经在 iOS6 中登录 FB 并且应用程序已经授权)被调用了两次: 一次使用 FBSessionStateOpen,一次使用 FBSessionStateOpenTokenExtended(来自 openSessionForPublishPermissions 调用)。 因此,_share 也被调用了两次,第一次是在 _prepareShareelse 部分(如果我已经拥有发布权限),第二次是在 openSessionForPublishPermissions 的完成处理程序中。 所以我在 Facebook 墙上有一个双重帖子,这是我第一次在应用程序中分享。我还收到了FBSession: It is not valid to reauthorize while a previous reauthorize call has not yet completed 的崩溃报告(我无法再次发生)。

处理这种情况的正确方法是什么?

【问题讨论】:

标签: ios objective-c facebook facebook-ios-sdk


【解决方案1】:

从设计上看,Facebook SDK 似乎保留了对块处理程序的引用,即使在它们被调用之后也是如此。因此,在您调用 openActiveSessionWithReadPermissions 时,可能会多次调用完成处理程序,以防会话状态发生变化。见Facebooks comment on this issue here

作为一种解决方法,您可能希望实现自己的机制来确保处理程序只被触发一次:

__block FBSessionStateHandler runOnceHandler = ^(FBSession *session,
                                             FBSessionState status,
                                             NSError *error) { /* YOUR CODE HERE */ };

...

 [FBSession openActiveSessionWithReadPermissions:YOUR_PERMISSIONS
                                       allowLoginUI:YES
                                  completionHandler:^(FBSession *session,
                                                      FBSessionState status,
                                                      NSError *error) {
                                      if (runOnceHandler) {
                                          runOnceHandler(session, status, error);
                                          runOnceHandler = nil;
                                      }

                                  }
     ];

【讨论】:

    【解决方案2】:

    你可以用这个

    - (IBAction)facebookBasti:(id)sender {
    if(FBSession.activeSession.isOpen){
    
        [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
            if (!error) {
    
                NSLog(@" Email = %@",[user objectForKey:@"email"]);
            }
        }];
    
        NSLog(@"POST TO WALL -- %@",FBSession.activeSession.accessToken);
        [self publishFacebook];
    
    }
    else {
        // try to open session with existing valid token
        NSArray *permissions = [[NSArray alloc] initWithObjects:
                                @"publish_actions",@"email",
                                nil];
        FBSession *session = [[FBSession alloc] initWithPermissions:permissions];
        [FBSession setActiveSession:session];
        if([FBSession openActiveSessionWithAllowLoginUI:NO]) {
            // post to wall
            [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
                if (!error) {
    
                    NSLog(@" Email = %@",[user objectForKey:@"email"]);
                }
            }];
    
            NSLog(@"POST TO WALL -- %@",FBSession.activeSession.accessToken);
            [self publishFacebook];
        } else {
            // you need to log the user
            NSLog(@"login");
    
            [FBSession openActiveSessionWithPermissions:permissions
                                           allowLoginUI:YES
                                      completionHandler:^(FBSession *session,
                                                          FBSessionState state,
                                                          NSError *error) {
                                          NSLog(@"POST TO WALL -- %@",FBSession.activeSession.accessToken);
                                          [self publishFacebook];
    
                                      }];
        }
    }
    

    }

    并发布Facebook方法

       -(void)publishFacebook
       {
    NSMutableDictionary *postParams2= [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                                       haberLink, @"link",
                                       @"abc.com", @"name",
                                       title, @"caption",
                                       desc, @"description",
                                       nil];
    
    [FBRequestConnection
     startWithGraphPath:@"me/feed"
     parameters:postParams2
     HTTPMethod:@"POST"
     completionHandler:^(FBRequestConnection *connection,
                         id result,
                         NSError *error) {
         NSString *alertText;
         if (error) {
             alertText = [NSString stringWithFormat:
                          @"error: domain = %@, code = %d",
                          error.domain, error.code];
         } else {
             alertText = [NSString stringWithFormat: @"Shared Facebook"];
    
    
    
             [[[UIAlertView alloc] initWithTitle:@"Shared Facebook"
                                         message:alertText
                                        delegate:self
                               cancelButtonTitle:@"Ok"
                               otherButtonTitles:nil]
              show];
    
         }
     }];
    

    }

    【讨论】:

    • 感谢您的帮助,但我真的很想了解我是否做错了什么以及处理这种 Facebook 行为的正确方法
    • 在你的准备分享方法中你已经发布了,当你调用_share方法再次发布时
    • 是的,但是一个在 if 块中(如果我没有发布权限,请求它,然后分享),另一个在 else 块中(如果我已经有发布权限,只是分享)。问题是 _share 在由 FBSessionStateOpenTokenExtended 触发的 _prepareshare 的 else 语句中被调用,而 requestNewPublishPermissions 尚未调用其完成处理程序,当再次调用 _share 时
    【解决方案3】:

    请阅读Upgrading from 3.0 to 3.1,尤其是分别请求读写权限的段落。 Facebook SDK 似乎不适合这种方式使用。

    您现在需要分别(并按此顺序)请求阅读和发布权限。您很可能会在应用启动且用户首次登录时请求个性化的读取权限。稍后,如果合适,您的应用可以在打算将数据发布到 Facebook 时请求发布权限。

    重要的是,您不要简单地尝试背靠背调用这两个单独的方法来替换任何一个已弃用的函数。

    我想知道您是如何解决这个问题的。顺便说一句,我得到了相同的崩溃报告(FBSession:在之前的重新授权调用尚未完成时重新授权无效)。

    【讨论】:

      猜你喜欢
      • 2013-03-24
      • 1970-01-01
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 2014-08-16
      • 2021-06-04
      • 2015-12-18
      • 1970-01-01
      相关资源
      最近更新 更多