簡體   English   中英

Facebook SDK 3.1 iOS:如果用戶從Facebook設置中刪除應用,則處理登錄

[英]Facebook SDK 3.1 iOS: Handle login if user remove app from Facebook Settings

我想在我的應用程序中添加一些Facebook集成。 在這一點上,我已經成功登錄,發布到朋友牆,檢索朋友列表等。除了一件事之外,其他一切都還可以。

如果用戶從您的Facebook設置/應用程序中刪除了該應用程序 ,然后輸入iOS應用程序,則該代碼無法識別該Facebook應用程序已從用戶設置中刪除,並假定已登錄(這是因為如果用戶嘗試將其發布到朋友的牆上,則該應用不執行任何操作)。

然后,用戶關閉iOS應用並重新啟動...通過重新啟動,iOS應用“已修復”並檢測到用戶不再登錄。

為了將登錄流程帶給用戶,我無法設法檢測到用戶從設置中刪除Facebook應用之后的那一刻...

這是我的代碼:

在我的應用的第一個場景中...

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密碼后才發現的,我們無法再進行身份驗證。 手動重新同步/清除帳戶會話可以使他們再次登錄。

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

實際上,解析和檢測這些類型的錯誤非常困難,原因有兩個:

  1. 在您實際嘗試並失敗FBRequest(或類似請求)之前,我無法找出任何方法來檢測此問題,並且
  2. 從失敗的FBRequest傳遞的NSError對象很難以任何功能方式解析和使用。

下面是我寫的一個瘋狂方法,實際上是為了吸引一個通宵人員而寫的。 它處理來自失敗的FBRequest嘗試的NSError *error對象,並將其傳遞給相關方法,或者顯示我可以找到的最明智的錯誤(或觸及所有錯誤)。

請注意注釋-特別是關於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錯誤字典將具有以下形式

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM