2013-02-20 13 views
1

我正在使用Facebook集成的社交框架Facebook &。爲此我跟着這link 一切工作正常,除非我的應用程序收到ACAccountStoreDidChangeNotification,它崩潰。 應用程序崩潰時在iOS 6+中處理Facebook和Twitter的ACAccountStoreDidChangeNotification

1)我第一次安裝應用程序&用戶沒有在設置中配置Facebook/Twitter帳戶。

2)當我打電話給Facebook/Twitter的任何方法時,它給了我錯誤代碼6,因爲我沒有帳戶配置,這是正確的。

3)我點擊HOME按鈕,所以我的應用程序進入背景&在Settigs中添加帳戶。

4)一旦我配置了賬戶&回到應用程序,我的應用程序從後臺啓動&收到ACAccountStoreDidChangeNotification。

5)在ACAccountStoreDidChangeNotification的選擇器中,我的帳戶對象爲零,所以我的應用程序崩潰。所以,我檢查了零

這裏是我的代碼

#pragma mark - Request Facebook Account Access 

-(void)requestFacebookAccountAccess 
{ 
    requestType = kNoOpRequest; 
    // Register for Account Change notification 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(accountChanged:) name:ACAccountStoreDidChangeNotification object:nil]; 

    self.accountStore = [[ACAccountStore alloc]init]; 
    ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; 

    // Set facebook permissions 
    NSArray *permissions = nil; 

    // We need to ask for Basic permission first 
    if (![kUserDefaults boolForKey:FACEBOOK_BASIC_PERMISSION]) { 
     permissions = @[@"email",@"user_about_me",@"user_location",@"friends_about_me"]; 
     self.isBasicFacebookPermissionsRequested = YES; 
    } 
    else { 
     permissions = @[@"email",@"user_about_me",@"user_location",@"friends_about_me",@"publish_stream"]; 
    } 

    //use ACAccountStore to help create your dictionary 
    NSDictionary *dictFacebook = @{ 
     ACFacebookAppIdKey: kFacebookAppIDKey, 
     ACFacebookPermissionsKey: permissions, 
     ACFacebookAudienceKey: ACFacebookAudienceFriends 
    }; 

    [self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFacebook completion:^(BOOL granted, NSError *error) { 
     if (granted) { 

      if (self.isBasicFacebookPermissionsRequested) { 
       self.isBasicFacebookPermissionsRequested = NO; 
       [kUserDefaults saveBasicFacebookPermissionsGrantedStatus:YES]; 
       //[self requestFacebookAccountAccess]; 
      } 

      // User granted permission to Accout 
      NSArray *accountsArray = [self.accountStore accountsWithAccountType:FBaccountType]; 

      if ([accountsArray count]>0) { 
       //It will always be the last object with SSO 
       self.facebookAccount = [accountsArray lastObject]; 
       NSLog(@"In %s::IS MAIN THREAD:- %@",__PRETTY_FUNCTION__,[NSThread isMainThread][email protected]"YES":@"NO"); 

       if ([self.delegate respondsToSelector:@selector(didFacebookAccountAccessGranted)]) { 
         dispatch_async(dispatch_get_main_queue(),^{ 
          [self.delegate didFacebookAccountAccessGranted]; 
         }); 
       } 
      } 
      else { 
       [self showAlertWithTitle:@"Error" andMessage:@"You don't have any Facebook accounts set up yet.Please set a Facebbok account and try again."]; 
      } 
     } 
     else { 
      DLog(@"User denied permission to Accout::Localized Error:- %@",error.localizedDescription); 
      if([error code]==6) { 
       [self showAlertWithTitle:@"Error" andMessage:@"Please setup facebook account from Settings"]; 
       if ([self.delegate respondsToSelector:@selector(didFacebookAccountAccessDenied:)]) { 
        dispatch_async(dispatch_get_main_queue(),^{ 
         [self.delegate didFacebookAccountAccessDenied:error]; 
        }); 
       } 
      } 
      else if ([self.delegate respondsToSelector:@selector(didFacebookAccountAccessDenied:)]) { 
       dispatch_async(dispatch_get_main_queue(),^{ 
        [self.delegate didFacebookAccountAccessDenied:error]; 
       }); 
      } 

      else { 
       // User denied permission to Account 
       [self showAlertWithTitle:@"Error" andMessage:[NSString stringWithFormat:@"User denied permission to Accout::Error:- %@",error.localizedDescription]]; 
      } 
     } 
    }]; 
} 



#pragma mark - Get Logged In User Info 

-(void)getLoggedInUserInfo 
{ 
    NSURL *requestURL = [NSURL URLWithString:@"https://graph.facebook.com/fql"]; 
    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"SELECT current_location,uid,name,sex,birthday,email,pic FROM user WHERE uid=me()",@"q", nil]; 
    requestType = kGetLoggedInUserInfoRequest; 
    [self requestDataUsingURL:requestURL parameters:dict requestMethod:SLRequestMethodGET]; 
} 

#pragma mark - Request Data From Facebook 

-(void)requestDataUsingURL:(NSURL*)requestURL parameters:(NSDictionary*)params requestMethod:(SLRequestMethod)reuqestMethod 
{ 

    SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook 
              requestMethod:reuqestMethod 
                 URL:requestURL 
               parameters:params]; 
    request.account = self.facebookAccount; 

    [request performRequestWithHandler:^(NSData *data, 
             NSHTTPURLResponse *response, 
             NSError *error) 
    { 
     NSDictionary *dictData =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 
     if(!error) 
     { 
      if([dictData objectForKey:@"error"]!=nil) 
      { 
       DLog(@"Request Data From Facebook Errro:- %@",dictData); 
       [self attemptRenewCredentials]; 
       if ([self.delegate respondsToSelector:@selector(didGetFacebookError:)]) { 
        dispatch_async(dispatch_get_main_queue(),^{ 
         [self.delegate didGetFacebookError:dictData]; 
        }); 
       } 
      } 
      else { 
       // Process the response 
       //NSLog(@"Response Dictionary contains: %@", dictData); 
       if ([self.delegate respondsToSelector:@selector(didPostToFacebook:)]) { 
        dispatch_async(dispatch_get_main_queue(),^{ 
         [self.delegate didPostToFacebook:dictData]; 
        }); 
       } 
      } 
     } 
     else{ 
      if ([self.delegate respondsToSelector:@selector(didGetFacebookError:)]) { 
       dispatch_async(dispatch_get_main_queue(),^{ 
        [self.delegate didGetFacebookError:dictData]; 
       }); 
      } 
      else { 
       [self showAlertWithTitle:@"Error" andMessage:@"Some error occured while processing Facebook request"]; 
      } 
     } 

    }]; 
} 

-(void)accountChanged:(NSNotification *)notif 
{ 
    if (self.facebookAccount!=nil) { 
     [self attemptRenewCredentials]; 
    } 
    else { 
     [self requestFacebookAccountAccess]; 
    } 
} 

#pragma mark - Attempt to Renew Credentials 

-(void)attemptRenewCredentials 
{ 
    [self.accountStore renewCredentialsForAccount:(ACAccount *)self.facebookAccount completion:^(ACAccountCredentialRenewResult renewResult, NSError *error){ 
     if(!error) 
     { 
      switch (renewResult) { 
       case ACAccountCredentialRenewResultRenewed: 
        NSLog(@"Good to go"); 
        [self againRequestFacebook]; 
        break; 
       case ACAccountCredentialRenewResultRejected: 
        NSLog(@"User declined permission"); 
        break; 
       case ACAccountCredentialRenewResultFailed: 
        NSLog(@"non-user-initiated cancel, you may attempt to retry"); 
        break; 
       default: 
        break; 
      } 

     } 
     else{ 
      //handle error gracefully 
      NSLog(@"error from renew credentials%@",error); 
     } 
    }]; 
} 

-(void)againRequestFacebook 
{ 
    switch (requestType) { 
     case kGetLoggedInUserInfoRequest: 
      [self getLoggedInUserInfo]; 
      break; 
     case kGetFriendsInfoRequest: 
      [self getFacebookFriendsInfo]; 
      break; 
     case kPostToWallRequest: 
      [self postToFacebookWallInBackgroundForUserId:fbUserIdForPost withParams:paramsToPost]; 
      break; 
     default: 
      break; 
    } 
} 

#pragma mark - Remove Observer for Notification 

-(void)dealloc 
{ 
    requestType = kNoOpRequest; 
    [[NSNotificationCenter defaultCenter] removeObserver:ACAccountStoreDidChangeNotification]; 
} 

但accountChanged方法被調用多次。 這有什麼問題?我該如何處理這種情況? 高度讚賞任何形式的幫助。

在此先感謝。

回答

-1

我面臨同樣的問題......所以我用一個變通通過在一個NSUserDefaults的BOOL值時,執行accountChanged方法只有一次

-(void)accountChanged:(NSNotification *)notif 
{ 
    BOOL calledAccountChanged =[[[NSUserDefaults standardUserDefaults] objectForKey:DidAccountChanged] boolValue]; 
    if(!calledAccountChanged) 
    { 
     if (self.facebookAccount!=nil) { 
      [self attemptRenewCredentials]; 
     } 
     else { 
      [self requestFacebookAccountAccess]; 
     } 
    } 
} 

然後我們就可以在後面的代碼更改DidAccountChanged值。 ..

如果你有更好的解決方案,請發佈它...

+0

感謝您的回覆。如果用戶每天更改帳戶,我們應該怎麼做?我們應該在哪裏重置calledAccountChanged? – iOSAppDev 2013-02-25 11:27:58

+0

' - (void)accountChanged:(NSNotification *)notif'這個方法只會在facebook賬戶被更改並且應用程序在後臺時被調用。如果關閉應用程序,更改FB帳戶並再次打開應用程序,通知將無法工作。所做的就是將FB UID存儲在** NSUserDefaults **中,當應用程序打開時,檢查存儲的FB UID是否與當前的一致。如果它不匹配change'calledAccountChanged'。 – 2013-02-25 15:04:07

+0

感謝您的回覆。我會試試這個,讓你知道。 – iOSAppDev 2013-02-27 07:49:04