为Facebook&处理ACAccountStoreDidChangeNotification iOS 6+推特 [英] Handle ACAccountStoreDidChangeNotification for Facebook & Twitter in iOS 6+

查看:184
本文介绍了为Facebook&处理ACAccountStoreDidChangeNotification iOS 6+推特的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Facebook的社交框架和Twitter整合。为此,我按照链接
一切正常,除非我的应用程序收到ACAccountStoreDidChangeNotification,它崩溃了。
应用程序崩溃

I am using Social framework for Facebook & Twitter integration. For this I followed this link Everything is working fine except when I app receives ACAccountStoreDidChangeNotification , it crashes. App crashes when

1)我第一次安装应用程序&用户没有在设置中配置Facebook / Twitter帐户。

1) I installed app for first time & user don't have Facebook / Twitter account configured in Settings.

2)当我调用Facebook / Twitter的任何方法时,它会给我错误代码6,因为我不喜欢我的帐户配置正确。

2) When I call any method of Facebook / Twitter , it gives me error code 6 as I don't have account configured which is right.

3)我点击HOME按钮,我的应用程序进入后台&在Settigs中添加帐户。

3) I click on HOME button so my app enters background & add account in Settigs.

4)我配置帐户&回到应用程序,我的应用程序从后台启动收到ACAccountStoreDidChangeNotification。

4) Once I configured account & come back to app , my app launches from background & receives ACAccountStoreDidChangeNotification.

5)在ACAccountStoreDidChangeNotification的选择器中,我的帐户对象为零,所以我的应用程序崩溃了。所以我检查了零

5) In selector of ACAccountStoreDidChangeNotification my account object is nil so my app crashes. So I checked for the nil

这是我的代码

    #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]?@"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方法。
这有什么问题?我该如何处理这种情况?
非常感谢任何形式的帮助。

But accountChanged method gets called multiple times. What is wrong in this ? How can I handle this situation ? Any kind of help is highly appreciated.

提前致谢。

推荐答案

我面临同样的问题...所以我通过在NSUserDefaults中使用BOOL值来执行accountChanged方法只使用一次

I am facing the same problem...so i used a work around by having a BOOL value in NSUserDefaults to execute accountChanged method only once

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

然后我们可以更改DidAccountChanged值稍后在代码中...

Then we can change DidAccountChanged value later in the code...

如果你有更好的解决方案,请发布它...

If you have better solution do post it...

这篇关于为Facebook&处理ACAccountStoreDidChangeNotification iOS 6+推特的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆