2012-10-11 42 views
10

Tôi muốn đưa một số tích hợp Facebook vào ứng dụng của mình. Tại thời điểm này tôi đã quản lý để đăng nhập, gửi cho bạn bè tường, lấy danh sách bạn bè, vv Tất cả mọi thứ là OK ngoại trừ một điều ...Facebook SDK 3.1 iOS: Xử lý đăng nhập nếu người dùng xóa ứng dụng khỏi Cài đặt Facebook

Nếu người dùng xóa ứng dụng khỏi your Facebook settings/Applications và sau đó nhập vào ứng dụng iOS, mã không nhận ra rằng ứng dụng Facebook đã bị xóa khỏi cài đặt người dùng và giả định rằng đã đăng nhập (đây là vấn đề vì nếu người dùng cố gắng đăng lên tường của bạn bè, ứng dụng sẽ không làm gì).

Sau đó, người dùng đóng ứng dụng iOS và relaunches nó ... Với relaunch này, ứng dụng iOS "là cố định" và phát hiện rằng người dùng không còn đăng nhập.

tôi không thể quản lý để phát hiện thời điểm ngay sau khi người dùng xóa các ứng dụng facebook từ các thiết lập nhằm đem lại luồng đăng nhập cho người dùng ...

đây là mã của tôi:

tại hiện trường đầu tiên của ứng dụng của tôi ...

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

Đây là mã cho 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]; 
    }]; 
} 

Mã cho 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]; 
    } 
} 

Cảm ơn bạn rất nhiều!

+0

Bạn giải quyết vấn đề này như thế nào? – SAHM

+0

Tôi chưa giải quyết được ...: C – Axort

+0

Câu trả lời đó đã giúp tôi http://stackoverflow.com/questions/12745235/handle-invalid-accesstoken-with-fbsession-openactivesessionwithreadpermissions-i – michael23

Trả lời

0

Tôi có cùng sự cố và không thể tìm thấy tài liệu thích hợp về mã lỗi trên trang web SDK của Facebook.

Tôi đã giải quyết sự cố bằng cách so sánh giá trị [error code]; hoặc [error userInfo];.

Phiên của bạn sẽ có tình trạng FBSessionStateClosedLoginFailed và UserInfo từ điển của lỗi sẽ có dạng sau

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

Trên mã lỗi Mặt khác thấy tôi 2 để bạn có thể xử lý nó ở phần cuối của sessionStateChanged :: : chức năng

- (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]; 
} 
} 
+0

Xin chào! Cảm ơn bạn đã trả lời ... Trên thực tế, trong phương thức sessionStateChanged, lỗi luôn là 0. Tôi không biết tại sao: C. – Axort

+0

nếu lỗi là không, nó không thể là trường hợp FBSessionStateClosedLoginFailed –

+0

retrieveUSerPermissions là gì? – Dejell

3

Nó thực sự rất khó để phân tích ra và phát hiện các loại lỗi vì hai lý do:

  1. tôi không thể tìm ra cách nào để phát hiện vấn đề này cho đến khi bạn thực sự cố gắng và thất bại một FBRequest (hoặc tương tự), và
  2. Đối tượng NSError truyền từ các thất bại FBRequest là ngớ ngẩn khó để phân tích và sử dụng trong bất kỳ cách nào chức năng.

Dưới đây là phương pháp điên rồ mà tôi đã viết trong khi nghĩa đen kéo toàn bộ để giải quyết vấn đề này. Nó xử lý đối tượng NSError *error từ nỗ lực FBRequest không thành công và chuyển nó đến các phương thức có liên quan HOẶC hiển thị lỗi hợp lý nhất mà tôi có thể tìm thấy (hoặc chạm vào phần bắt đáy).

Lưu ý các nhận xét - đặc biệt là xung quanh innerErrorparsedResponse - chi tiết những gì tôi đã khám phá cho đến thời điểm này. Chúc may mắn, dũng cảm người lính:

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

    } 
} 
5

tôi thấy điều này xảy ra với bản thân mình cũng .... Nó được phát hiện khi người dùng thay đổi mật khẩu facebook của họ, và chúng tôi không còn có thể xác thực. Thực hiện việc đồng bộ hóa thủ công/xóa phiên tài khoản cho phép họ đăng nhập lại.

-(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... 
    }]; 
      } 
     } 
    } 
Các vấn đề liên quan