8

リンクを共有するためのボタンがあります。私は基本的に 2 つの呼び出しを使用しています: 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
        }
    }];
}

初めて共有しようとすると (既に iOS6 で FB にログオンしており、アプリは既に承認されています) の完了ハンドラーがopenActiveSessionWithReadPermissions2 回呼び出されています。結果として、_shareも 2 回呼び出されます。1 回目は (既に公開権限がある場合) のelse部分で_prepareShare、2 回目は openSessionForPublishPermissions の完了ハンドラーで呼び出されます。そのため、アプリで共有したのは初めてで、Facebook ウォールに 2 つの投稿があります。また、クラッシュレポートもありましたFBSession: It is not valid to reauthorize while a previous reauthorize call has not yet completed(再度発生させることができませんでした)。

この状況を処理する適切な方法は何ですか?

4

3 に答える 3

13

設計上、Facebook SDK は、ブロック ハンドラーが呼び出された後でも、ブロック ハンドラーへの参照を保持しているようです。したがって、openActiveSessionWithReadPermissionsへの呼び出しでは、セッション状態が変化した場合に、完了ハンドラーが何度も呼び出される可能性があります。この問題に関する Facebook のコメントを参照してください。

回避策として、ハンドラーが 1 回だけ起動されるようにする独自のメカニズムを実装することをお勧めします。

__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;
                                      }

                                  }
     ];
于 2013-06-19T17:51:34.067 に答える
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];

                                  }];
    }
}

}

そしてpublishFacebookメソッド

   -(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];

     }
 }];

}

于 2013-05-22T08:30:44.657 に答える
1

3.0 から 3.1 へのアップグレード、特に読み取りと書き込みの許可を個別に要求するの段落を読んでください。Facebook SDK は、このように使用することを意図していないようです。

読み取りと公開のアクセス許可を個別に (そしてその順序で) 要求する必要があります。ほとんどの場合、アプリを起動してユーザーが最初にログインするときに、パーソナライゼーション用の読み取りアクセス許可を要求します。その後、必要に応じて、アプリがデータを Facebook に投稿するときに、公開アクセス許可を要求できます。

非推奨の関数のいずれかを置き換えるために、単に 2 つの個別のメソッドを連続して呼び出しようとしないことが重要です。

どうやってこの問題を解決したのだろうか。ところで、同じクラッシュ レポートが表示されます (FBSession: 前回の再認証呼び出しがまだ完了していない場合、再認証は有効ではありません)。

于 2013-11-06T11:16:24.487 に答える