Facebook SDK 3.1 iOS:如果用户从Facebook设置中删除应用,则处理login

我想在我的应用程序中join一些Facebook集成。 在这一点上,我已经设法login,张贴到朋友墙上,检索朋友列表等,除了一件事以外,一切都可以。

如果用户从Facebook设置/应用程序中删除应用程序 ,然后进入iOS应用程序,则代码无法识别Facebook应用程序已从用户设置中删除,并假定已login(这是问题,因为如果用户试图张贴到朋友的墙上,应用程序什么都不做)。

然后,用户closuresiOS应用程序并重新启动它…随着这个重新启动,iOS应用程序“是固定的”,并检测到用户不再login。

我无法设法检测到用户从设置中删除Facebook应用程序的时刻,以便将loginstream程传递给用户…

这是我的代码:

在我的应用程序的第一个场景…

if([FBSession activeSession].state == FBSessionStateCreatedTokenLoaded) { NSLog(@"Logged in to Facebook"); [self openFacebookSession]; UIAlertView *alertDialog; alertDialog = [[UIAlertView alloc] initWithTitle:@"Facebook" message:@"You're already logged in to Facebook" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; [alertDialog show]; [alertDialog release]; return YES; } else{ NSLog(@"Not logged in to Facebook"); //Show the login flow return NO; } 

这是openFacebookSession的代码

 -(void)openFacebookSession { NSArray *permissions = [[NSArray alloc] initWithObjects: @"publish_stream", nil]; [FBSession openActiveSessionWithPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceFriends allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) { [self sessionStateChanged:session state:status error:error]; }]; } 

sessionStateChanged的代码…

 -(void)sessionStateChanged:(FBSession *)session state:(FBSessionState)state error:(NSError *)error { switch (state) { case FBSessionStateOpen: { NSLog(@"Session opened"); } break; case FBSessionStateClosed: case FBSessionStateClosedLoginFailed: [FBSession.activeSession closeAndClearTokenInformation]; break; default: break; } if (error) { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:error.localizedDescription delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alertView show]; } } 

非常感谢你!

我发现这种情况也发生在我自己身上……当用户更改他们的Facebook密码,并且我们无法再进行身份validation时,就会发现这一情况。 手动重新同步/清除帐户会话允许他们再次login。

 -(void)syncFacebookAccount { [self forceLogout]; ACAccountStore *accountStore = [[ACAccountStore alloc] init]; ACAccountType *accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:@"com.apple.facebook"]; if (accountStore && accountTypeFB) { NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB]; id account; if (fbAccounts && [fbAccounts count] > 0 && (account = [fbAccounts objectAtIndex:0])) { [accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) { // Not actually using the completion handler... }]; } } } 

实际上很难parsing出这些types的错误,原因有二:

  1. 我找不出任何方法来检测这个问题,直到你实际尝试和失败的FBRequest(或类似),和
  2. 从失败的FBRequest传递的NSError对象很难以任何function的方式parsing和使用。

下面是我写的疯狂的方法,而从字面上拉一个全能的处理这个。 它处理来自失败的FBRequest尝试的NSError *error对象,并将其传递给相关的方法,或者显示我能find的最明智的错误(或者触发底部的catch-all)。

注意注释 – 特别是在innerErrorparsedResponse – 详细说明了迄今为止我发现的内容。 祝你好运,勇敢的士兵:

 - (void)handleFacebookError:(NSError *)error withPermissionType:(RMFacebookPermissionsType)type // this is just a typedef enum specifying Write or Read permissions so I can react accordingly withCompletion:(void (^)(BOOL retry))completionBlock { newMethodDebugLog; NSParameterAssert(error); NSParameterAssert(type); NSParameterAssert(completionBlock); // the completion block tells the controller whether the error is 'fatal' or can be recovered - if YES, it can be recovered // this is the parsed result of the graph call; some errors can appear here, too, sadly NSDictionary *parsedResponse = [error.userInfo objectForKey:@"com.facebook.sdk:ParsedJSONResponseKey"]; int parsedErrorCode = [[[[parsedResponse objectForKey:@"body"] objectForKey:@"error"] objectForKey:@"code"] intValue]; // this is an instance of NSError created by Facebook; it contains details about the error NSError *innerError = [error.userInfo objectForKey:@"com.facebook.sdk:ErrorInnerErrorKey"]; // innerError is usually un-recoverable if (innerError) { // innerError seems to be the response given in true HTTP problems; DebugLog(@"______innerError FOUND______"); DebugLog(@"innerError: %@",innerError); DebugLog(@"innerError.code: %d",innerError.code); // digging deep enough, you can actually find a coherent error message! :D DebugLog(@"innerError.localizedDescription: %@",innerError.localizedDescription); if (![alert isVisible]) { NSString *errorString = @"Facebook Connection Failed"; NSString *okString = @"OK"; alert = [[UIAlertView alloc] initWithTitle:errorString message:innerError.localizedDescription delegate:nil cancelButtonTitle:okString otherButtonTitles:nil]; [alert show]; } else { DebugLog(@"Alert already showing!"); } completionBlock(NO); } else if (parsedResponse && parsedErrorCode != 2) { // I honestly forget what error 2 is.. documentation fail :( // parsedResponses can usually be recovered DebugLog(@"parsed response values: %@",[parsedResponse allValues]); switch (parsedErrorCode) { case 2500: case 200: case 190: { DebugLog(@"parsedError code hit! forcing re-login."); // all errors in case 190 seem to be OAuth issues // http://fbdevwiki.com/wiki/Error_codes#Parameter_Errors // if needed, "error_subcode" 458 == user has de-authorized your app // case 2500 reported while grabbing from a photo album & not logged in // case 200 "requires extended permission: publish_actions" if (type == RMFacebookPermissionsTypeRead) { [self _getFacebookReadPermissionsWithUI:YES completion:completionBlock]; } else if (type == RMFacebookPermissionsTypeWrite) { [self _getFacebookWritePermissionsWithUI:YES completion:completionBlock]; } break; } default: completionBlock(YES); break; } } else { if (![alert isVisible]) { NSString *errorString = @"Facebook Error"; NSString *messageString = @"Mixture Photos was unable to connect to Facebook on your behalf. This is usually a temporary problem. Please try again later."; NSString *okString = @"OK"; alert = [[UIAlertView alloc] initWithTitle:errorString message:messageString delegate:nil cancelButtonTitle:okString otherButtonTitles:nil]; [alert show]; } else { DebugLog(@"Alert already showing!"); } completionBlock(NO); } } 

我有同样的问题,并找不到有关Facebook SDK网站上的错误代码的正确文档。

我通过比较[error code];解决了问题[error code];[error userInfo]; 值。

您的会话将具有状态FBSessionStateClosedLoginFailed和userInfo字典的错误将具有以下forms

 "com.facebook.sdk:ErrorLoginFailedReason" = "com.facebook.sdk:ErrorLoginFailedReason"; 

另一方面错误代码显示我2以便您可以在sessionStateChanged :::函数结束时处理它

 - (void)sessionStateChanged:(FBSession *)session state:(FBSessionState)state error:(NSError *)error { switch (state) { case FBSessionStateOpen: { //update permissionsArrat [self retrieveUSerPermissions]; if (!needstoReopenOldSession) { //First User information [self getUserInformation:nil]; } NSNotification *authorizationNotification = [NSNotification notificationWithName:facebookAuthorizationNotification object:nil]; [[NSNotificationCenter defaultCenter] postNotification:authorizationNotification]; } case FBSessionStateClosed: { break; } case FBSessionStateClosedLoginFailed: { [FBSession.activeSession closeAndClearTokenInformation]; break; } default: break; } if (error) { NSNotification *authorizationNotification = [NSNotification notificationWithName:faceBookErrorOccuredNotification object:error]; [[NSNotificationCenter defaultCenter] postNotification:authorizationNotification]; } }