16

アプリで Facebook SDK 3.0 を使用しています。Facebook にログインした後、delegate メソッドが 2 回呼び出されます。

- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
                            user:(id<FBGraphUser>)user {
    //loginThroughFb=TRUE;
    NSString *userId=[[NSString alloc] initWithString:[user id]];
    [self soapCallForLogin:@"" password:@"" deviceId:@"" fbid:userId];
    NSLog(@"%@",userId);
    [userId release];

}
4

7 に答える 7

9

「HelloFacebookSample」プロジェクトを試しましたが、メソッドは 1 回だけ呼び出されます。

したがって、このような場合の最善の解決策は、最後のユーザー オブジェクトへの参照を保持し、それを次の呼び出しを取得する新しいオブジェクトと比較することです。それらが等しい場合は、その呼び出しを無視できます。

- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user {
    if (![self isUser:cachedUser equalToUser:user]) {
        cachedUser = user;
        /// Do something
    }
}

- (BOOL)isUser:(id<FBGraphUser>)firstUser equalToUser:(id<FBGraphUser>)secondUser {
    return
        [firstUser.objectID isEqual:secondUser.objectID] &&
        [firstUser.name isEqual:secondUser.name] &&
        [firstUser.first_name isEqual:secondUser.first_name] &&
        [firstUser.middle_name isEqual:secondUser.middle_name] &&
        [firstUser.last_name isEqual:secondUser.last_name] &&
        ...
}
于 2013-06-18T21:06:09.333 に答える
7

私もこの問題を抱えていました。いハックでなんとか修正しましたが、機能します。FBLoginView デリゲートにカウンターを保持しています。fetchedUserInfo が呼び出されると、カウンターを確認します。ゼロより大きい場合は、戻ります。それ以外の場合は、次の 2 つのことを行います。1. メッセージ カウンターをインクリメントします。2. メッセージ カウンターを再びゼロにする遅延イベントを発生させます。

したがって、fetchedUserInfo メソッドは次のようになります。

- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
                        user:(id<FBGraphUser>)user {


       if ([self messageCounter] >0)
           return;
       else
           {
    self.messageCounter++;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        [self setMessageCounter:0];
    });}
// Do whatever you were going to do }
于 2013-06-20T08:23:36.360 に答える
3

私が直面した別の理由があるかもしれません。

私の状況:

  • ViewController A にはログインがあります (fbloginview とそのデリゲート セットを使用)
  • ユーザーは登録を選択し、別の fbloginview とそのデリゲート セットを使用して ViewController B に移動します。

上記はデリゲートを 2 回発火させます。

ViewController A の ViewWillDisappear でデリゲートを nil に設定することで、これを修正しました。

-(void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    fbLoginButton.delegate=self;
}
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    fbLoginButton.delegate=nil;
}
于 2014-09-23T09:40:02.480 に答える
1

このメソッドにスレッド セーフを追加する必要がありました。単純なクラス変数が機能しませんでした。ユースケースに応じて、次の 2 つのオプションが機能します。

- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user {
//self.executedOnce = NO; in the init method of this class
    @synchronized(self){
         if(!self.executedOnce) {
           //do something once per init of this class
            self.executedOnce = YES;
          }
    }

//OR- This will only execute once in the lifetime of the app, thus no need for the executedOnce flag
    static dispatch_once_t onceToken;
       dispatch_once(&onceToken, ^{
            //do something once per lifetime of the app
     });

}

于 2014-12-23T21:41:08.093 に答える