Facebook SDK Singleton在xcode之前自动login后?

我已经在Facebook教程中指导了Facebook SDK在APPDelegate中的工作,但是我正在尝试使用单例方法。 我发现的每个教程似乎都是针对SDK的一个较老的版本,但是我已经成功地使用了这个教程http://indiedevstories.com/2011/08/30/a-facebook-reusable-class/

我有两个问题,第一个贴在这里这是第二个:

我想要一个button发布到Facebook,但如果用户没有login,那么他们需要先login然后发布(不必先按一个单独的loginbutton)。 我可以很好地login,我可以发表很好,但我不能一起做。 如果没有login,邮政编码将显示login屏幕,但login后不会转到邮政屏幕。您必须再次按发布。 如果您尝试login但已经login,则不会有任何反应。 所以在button上我使用代码来login然后张贴,因为login只是已经跳过,如果已经login。我遇到的问题是邮政编码正在login代码后立即运行,所以在用户有一个机会login。 这导致2个popup窗口被打开(1login和1post显示login为尚未login)。

如何让我的代码等待用户login之前移动到代码中的下一行发布?

FacebookHelper.h

@interface FacebookHelper : NSObject <FBSessionDelegate, FBRequestDelegate, FBDialogDelegate, FBLoginDialogDelegate> { Facebook *_facebook; NSArray *_permissions; } @property (nonatomic,strong) Facebook *facebook; +(FacebookHelper *) sharedInstance; +(void)fbDidLogin; #pragma mark - Public Methods -(BOOL) isFBSessionValid; -(void) login; -(void) logout; -(void) postToWallWithDialogNewHighscore:(int)highscore; @end 

FacebookHelper.m

 @implementation FacebookHelper @synthesize facebook; #pragma mark - #pragma mark Singleton Variables static FacebookHelper *singletonDelegate = nil; #pragma mark - #pragma mark Singleton Methods +(FacebookHelper *)sharedInstance { @synchronized(self) { if (singletonDelegate == nil) { singletonDelegate = [[self alloc] init]; // Assignment not done here } } return singletonDelegate; } -(id)init { self = [super init]; if (self) { _facebook = [[Facebook alloc] initWithAppId:kAppId andDelegate:self]; // Restore previous session NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if ([defaults objectForKey:@"FBAccessTokenKey"] && [defaults objectForKey:@"FBExpirationDateKey"]) { _facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"]; _facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"]; } // } return self; } +(id)allocWithZone:(NSZone *)zone { @synchronized(self) { if (singletonDelegate == nil) { singletonDelegate = [super allocWithZone:zone]; // assignment and return on first allocation return singletonDelegate; } } //on subsequent allocation attemps, return nil return nil; } -(id)copyWithZone:(NSZone *)zone { return self; } #pragma mark - Facebook Delegate Methods -(void)fbDidLogin { NSLog(@"fbDidLogin"); NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:[_facebook accessToken] forKey:@"FBAccessTokenKey"]; [defaults setObject:[_facebook expirationDate] forKey:@"FBExpirationDateKey"]; [defaults synchronize]; } -(void)fbDidLogout { NSLog(@"fbDidLogout"); // Remove saved authorisation information if it exists NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if ([defaults objectForKey:@"FBAccessTokenKey"]) { [defaults removeObjectForKey:@"FBAccessTokenKey"]; [defaults removeObjectForKey:@"FBExpirationDateKey"]; [defaults synchronize]; } } #pragma mark - Public Methods -(NSMutableDictionary *) buildPostParamsWithHighScore:(int)highscore { NSString *customMessage = [NSString stringWithFormat:kCustomMessage, highscore, kAppName]; NSString *postName = kAppName; NSString *serverLink = [NSString stringWithFormat:kServerLink]; NSString *imageSrc = kImageScr; //Final params build NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys: //@"message", @"message", imageSrc, @"picture", serverLink, @"link", postName, @"name", @" ", @"caption", customMessage, @"description", nil]; return params; } -(BOOL) isFBSessionValid { // Check if there is a valid session //_facebook = [[Facebook alloc] initWithAppId:kAppId andDelegate:self]; _facebook.accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"FBAccessTokenKey"]; _facebook.expirationDate = [[NSUserDefaults standardUserDefaults] objectForKey:@"FBExpirationDateKey"]; NSLog(@"accessToken=%@ expirationDaate=%@",_facebook.accessToken,_facebook.expirationDate); if (![_facebook isSessionValid]) { NSLog(@"FacebookHelper isFBSessionValid = NO"); return NO; } else { NSLog(@"FacebookHelper isFBSessionValid = YES"); return YES; } return NO; } -(void) login { NSLog(@"FacebookHelper login"); _permissions = [NSArray arrayWithObjects:@"publish_stream", nil]; //@"read_stream", @"offline_access" [_facebook authorize:_permissions]; } -(void) logout { [_facebook logout]; } -(void) postToWallWithDialogNewHighscore:(int)highscore { NSMutableDictionary *params = [self buildPostParamsWithHighScore:highscore]; NSLog(@"Post Feed"); [_facebook dialog:@"feed" andParams:params andDelegate:self]; } @end 

button操作:

 - (IBAction)facebookTest:(id)sender { [[FacebookHelper sharedInstance] login]; [[FacebookHelper sharedInstance] postToWallWithDialogNewHighscore:123]; } 

我已经更新了单身人士课程,将分数发布到Facebook Wall。 看看新版本: http : //indiedevstories.com/2012/04/11/facebookscorer-post-highscores-to-users-facebook-wall/

这个新版本在需要授权和login时正确处理内部状态。

HTH

你需要做的是让你的postToWallWithDialogNewHighscore调用login,如果有必要,然后等待从FBSession代理回来。 那么你需要设置你的Facebook fbDidLogin委托,以便当它完成后发回消息。 有很多方法可以做到这一点(后loginselect器,NSNotificationCenter等)。 这样的事情应该工作(注意我为了方便,假设NSMutableDictionary * postParams伊维尔):

 -(void)doPost { NSLog(@"Post Feed"); [_facebook dialog:@"feed" andParams:postParams andDelegate:self]; } -(void)postToWallWithDialogNewHighscore:(int)highscore { postParams = [self buildPostParamsWithHighScore:highscore]; if (_facebook.isSessionValid) { [self doPost]; } else { //register an observer for FB login messages [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(postToWallObserver:) name:@"FBLoginComplete" object:nil]; [self login]; } } -(void)fbDidLogin { NSLog(@"token granted until %@", [_facebook expirationDate]); NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:[_facebook accessToken] forKey:@"FBAccessTokenKey"]; [defaults setObject:[_facebook expirationDate] forKey:@"FBExpirationDateKey"]; [defaults synchronize]; [[NSNotificationCenter defaultCenter] postNotificationName:@"FBLoginComplete" object:nil]; } -(void)fbDidNotLogin:(BOOL)cancelled { //do nothing as they didn't login } -(void) postToWallObserver:(NSNotification *) notification { if ([[notification name] isEqualToString:@"FBLoginComplete"]) { if ([_facebook isSessionValid]) { [self doPost]; } } [[NSNotificationCenter defaultCenter] removeObserver:self]; } 

注意:我没有编译这个代码,所以可能会有拼写错误等。